先给结论:当同一路径在不同层缓存中返回不同 robots.txt 内容时,不要从抓取日志推断谁对谁错,而应把每一层缓存实际返回的字节抓下来做逐字节对比,找出最早出现分歧的那一层。只有确认分歧源后,才决定是刷新缓存、改回源配置,还是调整回源路径。如果分歧发生在 CDN 边缘节点之间,清理单节点通常无效,需要看回源请求是否绕过了某层缓存。
两种情况的处理方向完全不同。内容不同指同一份文件被不同层改写,比如某层注入了额外规则、删掉了某段 Disallow,或把注释截断。版本不同指各层各自持有不同时间点的完整文件,内容结构一致但某几条规则有增删。
区分方法很直接:把各层返回的响应体保存为文件,用 diff 或校验和比对。如果差异只在个别行,且这些行在源站历史版本中都出现过,属于版本不同;如果出现了源站从未有过的行或格式变化,属于内容被改写。
这个判断会决定下一步动作。版本不同通常靠统一刷新或缩短缓存 TTL 解决;内容被改写则要检查中间层是否有注入、压缩或转码行为,单纯刷新可能反复出现。
如果多次从不同位置请求同一路径,只有部分节点返回旧版本,说明缓存刷新没有覆盖全部分片,或者部分节点的回源路径与其余节点不同。
此时要做的是:记录每个返回旧版本的节点标识和请求时间,然后对其中一个节点强制回源,观察它是否立即拿到新版本。如果强制回源后仍返回旧内容,问题在回源链路而非节点缓存;如果强制回源后变新,说明是缓存未过期,只需等待或主动清理。
实施动作上,优先确认回源请求是否真的到达源站。可以在源站侧观察对应时间窗口内是否有来自该层的请求记录。如果没有任何回源记录,说明该层在用本地副本响应,清理该层缓存是必要动作。这一步的结果会告诉你:是缓存策略问题,还是回源路由问题。前者改 TTL 或主动清理即可,后者需要检查回源域名解析和中间层配置。
例外情况:如果站点使用多级回源(边缘到中间层,中间层到源站),中间层可能缓存了旧版本并持续供给边缘。此时只清理边缘无效,必须从最靠近源站的那一层开始逐层清理,顺序反了会看到旧内容反复回流。
这说明分歧不在缓存之间,而在源站输出与缓存接收之间。常见原因是源站根据请求头、来源 IP 或路径大小写返回了不同内容,而缓存层恰好固定用某一种请求方式回源。
验证方法是:直接向源站发起与缓存层相同特征的请求(相同 Host、相同路径写法、相同 User-Agent),对比返回内容是否与缓存层一致。如果一致,说明源站本身就在按请求特征输出不同文件,缓存只是忠实保存了其中一份。
这时要回到源站配置,确认是否存在按环境、按域名或按协议分支输出的逻辑。修正源站使其对同一路径始终返回同一内容,再清理缓存。如果不修源站只清缓存,下一次回源仍会拉到那份「错误」版本。
Age、Cache-Control、ETag 或 Last-Modified,判断各层持有的版本时间。每一步的结果都决定下一步是否有必要执行。例如第三步已经让内容更新,就不需要走到第四步;第四步发现没有回源记录,说明问题在缓存层而非源站,第五步可以跳过。
需要单独说明一点:robots.txt 中的抓取限制只约束爬虫行为,不等于可靠的索引移除手段。即使某条 Disallow 生效,已收录的 URL 仍可能出现在结果中。因此当你在排查缓存一致性时,不要把「爬虫没来抓」和「索引已移除」当成同一件事。如果目标是让旧内容退出索引,仅靠 robots.txt 通常不够,还需要配合页面本身的 noindex 或移除动作,并且不同搜索引擎对这两者的支持情况需要分别核查。
另外,站点地图中列出的 URL 不保证被收录,HTTPS 也不保证内容安全无漏洞或排名提升。这些与缓存一致性是不同层面的问题,排查时不要混在一起判断。
假设一个场景:某路径的 robots.txt 在边缘节点 A 返回旧版、节点 B 返回新版,回源后两者都变新版。这只能说明缓存刷新存在延迟,不能据此推断旧版规则曾经生效或从未生效。要判断影响,还需要看该时间段内爬虫实际抓取的是哪个版本,而抓取记录本身也可能受缓存影响,不能单独作为结论依据。