先给结论:不要从“哪个版本是对的”入手,而要先固定一个可重复的请求路径,记录每一层返回的版本标识,再把差异归因到某一层。多层缓存下,搜索引擎收录对比出现版本不一致,通常不是单一故障,而是抓取层、缓存层、渲染层各自持有不同快照。定位动作是逐层剥离缓存并比对响应头、正文摘要和版本号,而不是直接清缓存。
一种常见反直觉结果是:你刚清理了CDN缓存,搜索引擎收录对比里显示的却是更旧的标题或摘要。此时有两个成立条件不同的解释。
解释一:清理动作只作用于边缘节点,源站或中间层仍返回旧版本。用户请求命中新边缘节点,看到新内容;爬虫请求命中了仍连旧中间层的节点,于是收录对比里出现旧版本。
解释二:清理动作触发了回源,但源站本身就有多个版本并存。例如应用服务器A返回v3,应用服务器B返回v2,清理缓存只是让爬虫随机命中了另一台源站。
这两个解释都符合“清缓存后版本更旧”的现象,不能用同一种处理方式。前者要查缓存层级,后者要查源站一致性。
能区分上述解释的证据来自响应头,而不是页面肉眼可见的内容。对同一个URL发起多次请求,记录以下字段:
Age:大于0说明命中了共享缓存;多次请求Age差异大,说明不同节点缓存状态不同。X-Cache或类似自定义头:若存在,可看出HIT/MISS;不同请求结果不一致,指向边缘层。ETag或Last-Modified:同一URL返回不同ETag,说明源站或中间层版本不一致,而不是边缘缓存过期。Vary:若按User-Agent或Accept-Encoding分版本,爬虫和浏览器可能命中不同缓存键。实际动作:连续请求同一URL十次,把每次的Age、ETag和正文中的版本标记记下来。如果ETag稳定但Age跳动,问题在缓存层;如果ETag本身就分叉,问题在源站或中间层。这个判断直接决定下一步是调整缓存键还是修复源站发布流程。
响应头只能说明“有差异”,不能说明差异内容是哪一层引入的。更可靠的做法是在HTML里放一个不依赖渲染的版本标记,例如注释或data-version属性,内容为发布批次号。这样每次抓取都能从原始响应里读到版本,而不是从渲染后的页面猜。
假设一个短例子:某页面发布v5后,搜索引擎收录对比显示标题仍是v3。你请求该URL,响应头ETag为v3,正文里的版本标记也是v3。这说明缓存层没有返回v5,问题在发布环节或源站回源路径,而不是搜索引擎缓存。若响应头ETag为v5但正文版本标记为v3,则说明缓存键或渲染层拼接了不同版本,需要检查边缘逻辑。
这个动作的结果会影响下一步:版本标记与ETag一致时,优先查发布流程;两者不一致时,优先查缓存键和渲染管线。不要在没有版本标记的情况下直接提交重新收录,否则无法判断提交后是否真的取到了新版本。
多层缓存问题常和抓取限制混在一起。需要明确:robots.txt的限制只约束抓取行为,不等于可靠的索引移除;页面被限制抓取后,已有索引仍可能保留旧版本一段时间。站点地图也不保证收录,它只是发现入口。因此,当你看到收录对比里版本陈旧时,先确认爬虫实际取到的响应,而不是先改robots.txt或重新提交站点地图。
可核对的证据是:用与爬虫一致的请求头请求URL,记录状态码、ETag、正文版本标记和Vary。若状态码为200且版本标记为旧,问题在缓存或源站;若状态码为403或503,则问题在访问控制层,缓存差异只是表象。
建议按以下顺序做,每一步都留下可核对记录:
Vary或User-Agent拆分。这个顺序的价值在于:它把“收录版本不对”拆成可验证的层,避免把缓存问题当成索引问题处理。请求量或抓取量归零不能单独证明某一层处理正确,因为回源失败、访问限制或缓存键变化都可能产生同样现象。定位一致性问题的核心,是让每一层都留下可对比的版本证据,再决定改哪一层。