robots协议:多层缓存返回不同版本时怎样定位一致性问题

📍 WDQWDWQD987AAAAA:216.73.216.175
📱 Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)
🔗 /26936b5c9e11.html
📄

robots协议:多层缓存返回不同版本时怎样定位一致性问题

先给有条件的结论:如果同一路径在不同网络位置返回的 robots.txt 内容不一致,优先怀疑 CDN 或反向代理的缓存键设计,而不是源站文件本身。只有当所有缓存层都确认回源同一份文件、且响应头中的缓存标识一致时,才应转向检查源站是否有按 User-Agent 或 IP 动态生成规则的逻辑。下面给出判断依据和一个会让上述结论失效的反例。

先判断不一致是缓存造成还是源站动态生成造成

两种成因的区分方法很直接:连续多次请求同一 URL,观察返回体是否在几个固定版本之间来回跳变。如果是缓存层各自持有不同副本,通常表现为稳定地按网络位置分组——同一出口 IP 段总是拿到同一版本。如果是源站动态生成,则同一出口也可能拿到不同版本,且跳变与请求头中的某些字段相关。

实际操作上,可以从三个位置分别取一次响应:源站直连、中间缓存节点、终端用户侧。比较三者的响应体哈希和 Cache-Control、Age、ETag 等头部。如果源站直连返回的版本与缓存节点返回的版本不同,而缓存节点的 Age 大于 0,基本可以判定是缓存未及时失效,而不是源站内容有分歧。

这一步的产出决定下一步方向:确认是缓存问题,就去查缓存键是否包含了不该包含的维度(比如把 User-Agent 或 Accept-Encoding 纳入了键,导致同一 URL 被拆成多份缓存);确认是源站问题,就去查规则生成逻辑里有没有读取请求头或地理位置。

缓存键、Vary 与失效策略是三个高发位置

多层缓存下,Vary 响应头是最容易被忽略的一环。如果源站对 robots.txt 返回了 Vary: User-Agent,中间缓存就会按 UA 分别存储副本。此时爬虫 UA 和普通浏览器 UA 拿到不同内容,看起来像"版本不一致",实际是缓存按规则分流。检查方法是:用两个不同的 UA 请求同一 URL,看返回体和 Vary 头是否对应。

缓存键设计同样关键。部分 CDN 默认把查询字符串纳入键,如果 robots.txt 被带上了无意义的查询参数(例如模板自动追加的版本号),就会产生多份互不关联的缓存副本。这种情况下,清除缓存只能解决一时,下次参数变化又会分裂。

失效策略则决定问题会不会反复出现。如果源站更新了 robots.txt 但没有主动 purge,各层缓存会按各自的 TTL 陆续过期,期间不同节点返回不同版本。要判断这是不是当前状况,可以对比各节点响应中的 Age 值:Age 差异大且内容不同,说明是过期时间不同步。

一个会让结论失效的反例

上述"先怀疑缓存"的结论在一种情况下不成立:源站按请求来源 IP 动态生成 robots.txt。假设某站点对来自特定网段的请求返回带 Disallow 的版本,对其他网段返回允许抓取的版本——这在多机房或灰度发布环境中可能出现。此时各层缓存返回不同版本,根源不在缓存,而在源站逻辑本身。

识别这个反例的证据是:源站直连时,用不同来源 IP 请求会得到不同内容,且响应中没有缓存命中标识(Age 为 0 或缺失)。如果出现这个特征,继续排查缓存就是走错方向,应该直接审查源站的规则生成代码和部署配置。

确认成因后应执行的动作

如果是缓存键包含了多余维度,动作是收窄缓存键,只保留路径,然后对 robots.txt 单独设置较短的 TTL 或配置主动 purge。做完这一步后,重新从三个位置取样验证,确认所有节点返回同一版本。验证通过才意味着可以进入下一步——检查该 robots.txt 的实际抓取限制是否与预期一致,因为内容一致不等于规则正确。

如果是源站动态生成,动作是先确认这种动态行为是否有意为之。若无意的,修正生成逻辑使其对所有请求返回同一文件;若有意为之,则需要评估不同版本对抓取限制的实际影响,并确保每个版本都符合预期。这一步完成后,同样要重新取样验证一致性,再判断是否需要调整站点地图或其他抓取相关配置。

需要提醒的是,robots.txt 的抓取限制本身不等于可靠的索引移除,即使各层版本一致,也不代表已收录的页面会因此消失。一致性问题解决后,索引层面的处理仍需单独评估。

图1 图2

nginx