先给结论:不要从“哪个缓存有错”入手,而要先固定一个可复现的请求路径,记录每一层返回的响应头、状态码和正文指纹,再对比差异出现在哪一层之后。多数所谓收录加速异常,实际是 CDN、反向代理、应用层缓存或页面缓存插件各自持有不同版本,导致抓取端反复看到内容不一致。定位顺序应是:先确认源站单一版本,再逐层穿透缓存比对,最后才决定清哪一层、保留哪一层。
假设你手头有一个旧产品页,需要下线旧型号信息,但保留仍然有效的配件说明。此时页面会同时存在“旧版全文”“新版删减版”两种可能。若只用浏览器刷新,你无法区分自己看到的是哪一层缓存。
先固定以下条件,再开始比对:
动作:用命令行工具分别请求一次,保存响应头和正文。结果如何影响下一步:如果两次请求的 ETag 或正文哈希不同,说明至少有一层在返回不同版本,此时不要急着清缓存,先进入分层比对。
多层缓存的典型链路是:浏览器缓存 → CDN 边缘节点 → 反向代理或负载均衡 → 应用层缓存 → 源站数据库或静态文件。定位一致性问题的关键是找到“差异第一次出现”的那一跳,而不是在最后一层猜测。
可执行步骤:
判断依据:如果源站返回 A 版本,CDN 返回 B 版本,反向代理返回 A 版本,那么差异最可能出在 CDN 边缘节点或 CDN 的缓存键规则上。如果源站和反向代理都返回 A,但应用层缓存返回 B,则问题在应用层缓存键或失效逻辑。若所有层都返回同一版本,但抓取端仍看到旧版本,则需要检查抓取端自身的缓存或代理链路,而不是继续清站点缓存。
两者都会表现为版本不一致,但处理方式不同。
缓存未失效的常见证据:响应头里 Age 较大,Cache-Control 的 max-age 尚未到期,且同一层在等待过期后自动返回新版本。此时动作是确认过期时间,必要时按既定流程触发刷新,而不是反复修改源站内容。
缓存键设计错误的常见证据:同一 URL 因 Cookie、语言头、设备类型或查询参数不同而命中不同缓存对象,导致一部分请求拿到旧版,另一部分拿到新版。此时动作是检查缓存键是否包含了不该包含的维度,或遗漏了应该包含的维度。结果如何影响下一步:如果缓存键把登录态和匿名态混在一起,应优先拆分缓存策略;如果缓存键遗漏了版本参数,则需要在发布流程中显式加入版本标识。
注意:请求量或抓取量归零不能单独证明某一层缓存处理正确,它也可能是抓取端临时降频、网络波动或 robots.txt 规则变化造成的。需要结合响应头和正文比对一起判断。
假设某页面在 CDN 上返回旧版,源站返回新版,且 CDN 响应头显示 Age: 3600,Cache-Control: max-age=7200。这组信息只能说明该边缘节点仍在缓存有效期内,不能直接证明源站发布流程有问题。
此时可以做的动作是:先记录该节点的缓存键和过期时间,等待过期后再次请求同一节点。如果过期后返回新版,说明是正常的缓存生命周期,不需要改动源站;如果过期后仍返回旧版,则继续检查 CDN 的缓存键规则和刷新记录。这个比较方法的关键是设置一个明确的观察窗口,而不是在窗口内反复清缓存。
对于旧内容退出场景,还应确认:旧版页面是否被其他页面引用、是否仍在站点地图中、是否被内部搜索或分类页链接。保留仍然有价值的部分时,建议把旧版内容合并到新版页面并设置正确的重定向,而不是让两个版本同时可访问。站点地图不保证收录,robots.txt 的抓取限制也不等于可靠的索引移除,因此版本一致性处理完以后,仍需要单独验证索引状态。
完成分层比对后,输出一份最小记录,包含:URL、请求时间、各层响应状态码、关键响应头、正文哈希、差异首次出现的层、假设原因、下一步动作。这样开发、运维和内容编辑可以各自认领:缓存键问题交给开发,过期时间问题交给运维,内容版本问题交给编辑。
如果确认是旧系统或旧合作关系留下的缓存层,且该层不再需要服务新内容,可以考虑退出该层,但必须先确认没有其他业务依赖它。退出的动作应分阶段:先停止写入新版本,再观察一段时间内是否仍有请求命中,最后才移除配置。每一步的结果都应记录,以便回退时有依据。
最终判断标准不是“所有层都返回同一个字符串”这么简单,而是:在约定的请求条件下,源站、各缓存层和抓取端看到的内容版本一致,且旧内容已经按计划退出或合并。达到这个状态后,再继续做收录加速相关的提交和验证,才不会把缓存不一致误判为索引问题。