先确认一件事:多层缓存返回不同版本,通常不是“哪一层坏了”,而是各层对同一请求的变体键、过期策略和回源条件不一致。定位顺序应从最靠近用户的层开始,逐层固定请求指纹,直到某两层对同一指纹给出不同响应体或不同状态码。批量查收录时,这种不一致会直接表现为同一批 URL 有的返回旧页面、有的返回新页面、有的返回重定向,最终让收录判断失去可比性。
多层缓存一般包括浏览器缓存、CDN 边缘节点、反向代理缓存和应用层对象缓存。它们可能各自按 URL、查询串、Cookie、User-Agent 或 Accept-Encoding 生成缓存键。只要某一层的键比另一层少一个维度,就会把不同变体折叠成同一个缓存条目。
实际动作是:为同一批 URL 构造一组固定请求,只改变一个变量,例如仅改变 Cookie 或仅改变查询串,然后记录每层返回的响应头、状态码和正文摘要。如果同一 URL 在 CDN 层返回新正文、在代理层返回旧正文,说明不一致发生在代理回源或代理缓存键这一层,而不是页面本身。这个结果决定下一步是检查缓存键配置,还是检查回源请求是否被改写。
面对不一致,常见做法有三种,选择取决于不一致是否影响收录判断的稳定性。
不要因为某一层返回旧版本就直接退出全部缓存。先判断旧版本是否只影响部分变体;如果只影响带跟踪参数的请求,保留缓存并规范化请求往往代价更低。
假设同一批 URL 中,A 页在两层缓存返回不同标题,B 页在所有层返回一致。可以构造如下对照:对 A 和 B 各发两次请求,一次带缓存绕过头,一次不带,比较正文摘要。如果 A 在绕过缓存后与 B 一致,说明差异来自缓存层;如果 A 绕过缓存后仍不同,说明差异来自页面生成或数据源。
这个对照的价值在于把“缓存问题”和“页面问题”分开。批量查收录时,如果混入大量缓存变体,抽样出的问题页面可能只是缓存副本,修复页面并不会改变批量结果。反过来,如果跳过这一步直接改页面,可能浪费一轮修复周期。
要让批量结果可复现,需要固定三件事:请求是否匿名、是否绕过缓存、以及比较的是状态码还是正文摘要。三者任意一项变化,都可能让同一批 URL 得出不同结论。
建议先在一个小样本上固定这三项,确认同一请求重复执行得到相同响应,再扩大到全量。如果小样本本身就不稳定,扩大批量只会放大噪声。此时应回到缓存键和回源条件,而不是继续增加样本量。
另外,robots.txt 的抓取限制不等于可靠的索引移除,站点地图也不保证收录。缓存一致只解决“你看到的是哪个版本”,不解决“该版本是否被索引”。两者需要分开判断,不能因为缓存统一了就推断收录问题已解决。
一旦确定不一致发生在某一层,最小验证是:只改这一层的配置或请求方式,重跑同一小样本,观察返回版本是否收敛。如果收敛,再扩大到批量;如果不收敛,说明还有第二层在参与变体折叠。
验证时记录每层响应头中的缓存命中标记和年龄字段,可以帮助判断是命中旧条目还是回源失败。但要注意,命中标记本身也可能被上一层缓存,不能单独作为结论。最终仍以同一请求指纹下的正文和状态码比较为准。
当批量查收录的结果开始稳定,下一步才是判断哪些 URL 真正需要处理。缓存一致只是让判断有可比性,不代替对页面可访问性和索引状态的实际检查。