先给结论:不要从最外层缓存开始逐个清,而是先固定一个可复现的请求标识,记录每一层返回的版本指纹,再用二分法缩小到第一处分叉点。下面用一个假设情境把决策过程走完。
假设某站点结构是:源站应用 → 应用层对象缓存 → 反向代理缓存 → CDN边缘节点。运维在排查时发现,同一条栏目页URL在三个位置看到三种结果:源站直连返回新版模板,反向代理返回旧版模板,CDN边缘返回的却是更早的一版。此时有两种看似合理的做法。
做法A:从CDN开始逐层清除,清完再观察。做法B:先不改任何缓存,先构造一组带唯一标识的请求,把每一层的返回固定下来,再决定清哪一层。假设情境下应选B,因为A会把证据一起清掉,之后无法判断分叉点原本在哪一层。
关键是让每一层的返回带上可区分的痕迹。可以在模板里输出一个仅用于排查的版本标记,例如在HTML注释中写入构建号:<!-- build:20240612-a -->。这个标记不参与展示,但能让你从响应体里直接读出是哪一版。
然后按层采集,且每次只改变一个变量:
把结果记录成“层—请求条件—版本标记”三列。如果某一层在命中与未命中时返回不同版本,说明该层的缓存键设计或失效逻辑有问题,而不是上游内容错。
拿到分层记录后,从源站往边缘方向看,找到第一个与上游不一致的层,那一层就是分叉点。假设记录显示:源站与应用层缓存未命中时都是新版,应用层缓存命中时是旧版,反向代理和CDN也都是旧版。那么分叉点在应用层缓存的命中路径上,下游只是忠实转发了旧内容。
这个判断会直接改变下一步动作:如果分叉点在应用层缓存,清CDN是无效动作,因为清完后边缘回源仍会拿到旧版;正确动作是先修正应用层缓存的键或失效条件,再让下游自然过期。
同样是旧版内容,原因可能不同,处理方式也不同。可以用两个可区分的信号来判断:
前者的修法是收敛缓存键,把不该参与键的维度剔除;后者的修法是检查失效广播的覆盖范围和重试机制。两者混在一起处理,往往会出现“清了又回来”的现象。
缓存一致后,页面返回的版本统一了,但这只是内容一致,不等于百度已经抓取到新版。这里要避免一个常见误判:把抓取量或某个统计归零当作处理正确的证据。抓取量下降还可能来自服务器响应变慢、robots.txt 临时调整、站点整体抓取配额变化等,不能单独证明缓存问题已解决。
同样,robots.txt 的抓取限制不等于可靠的索引移除,站点地图也不保证收录。缓存修复后应做的动作是:确认页面可正常访问、返回版本统一,然后让百度按正常抓取节奏重新获取。是否更新索引由后续抓取决定,不要用“提交了”当作“已生效”。
回到最初的两个做法:当你能复现问题时,先取证再清理;当问题只在生产环境偶发、无法复现时,才考虑先清理一层并立即记录清理前后的返回,用清理动作本身作为一次对照。代价是前者需要额外的排查标记和采集时间,后者会损失一部分现场证据。选择依据是问题是否可复现,而不是哪层缓存看起来更可疑。