如何检查网站死链:多层缓存返回不同版本时怎样定位一致性问题

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

如何检查网站死链:多层缓存返回不同版本时怎样定位一致性问题

先给结论:当同一批死链检查在不同节点得到不同结果时,不要急着认定哪一次是错的,而要先确认每个检查点是否绕过了全部缓存层,再比较各层返回的状态码与响应头。大多数“时好时坏”的死链报告,根源是检查请求命中了不同缓存版本,而不是链接本身在两种状态之间反复跳变。

先判断问题出在缓存版本,还是链接状态本身

两种情况的证据形态不同,处理顺序也应不同。

如果问题出在缓存版本,你会看到:同一 URL 在同一分钟内被不同节点请求,返回的状态码不一致,但响应头里的 Age、X-Cache、CF-Cache-Status 一类字段不同;或者带随机查询串请求时结果稳定,去掉查询串后结果开始漂移。这说明源站状态是一致的,是中间层保存了不同时期的副本。

如果链接状态本身在变,你会看到:绕过所有缓存直连源站,多次请求仍出现 200 与 404 交替,且响应体内容或长度也不同。这属于源站逻辑或数据问题,缓存只是把它放大成了“不同版本”。

选择依据很简单:先用一个已知会返回 404 的测试路径,分别从直连源站、经过 CDN、经过反向代理三层各请求几次。如果只有某一层结果异常,问题就锁定在该层;如果三层都不稳定,才回到源站排查。

用带唯一标识的请求把每一层分开验证

常规做法是直接刷新页面看结果,但浏览器和中间缓存都会复用旧副本,无法区分层次。更可靠的动作是给每次检查加一个唯一查询串,并显式要求不使用本地缓存。

  1. 对同一个待查 URL,附加一个随机参数,例如 ?probe=8f3a1c,让路径在每一层都被视为新资源。
  2. 分别从源站 IP、CDN 边缘节点、站内反向代理发起请求,记录状态码和响应头中的缓存命中字段。
  3. 对比三次结果:若附加随机参数后三层一致返回 404,说明死链真实存在,之前的不一致来自缓存;若仍不一致,继续查下一层。

这个动作的直接结果是:你能把“链接是否真的失效”和“缓存是否返回了旧版本”拆成两个独立结论。只有前者成立时,才需要进入替换或跳转处理;后者成立时,要处理的是缓存失效策略,而不是链接本身。

响应头里哪些字段能区分“缓存旧版本”和“源站真失效”

把注意力放在几个可观察字段上,而不是凭刷新次数猜测。

需要提醒的是,抓取量或请求量突然归零,并不能单独证明死链已被正确处理。它也可能是检查任务中断、缓存整体过期、或该路径被临时屏蔽造成的。要结合源站日志和响应头一起判断。

一个假设例子:三层结果不一致时怎么收敛

假设某栏目页在 CDN 节点返回 200,在反向代理层返回 404,直连源站返回 404。此时可以推断:反向代理和源站已经认为该页失效,CDN 仍在提供旧副本。

下一步动作是只对 CDN 层执行该路径的缓存清除,然后重新用带随机参数的请求验证。若清除后三层一致返回 404,就可以确认死链成立,进入替换或 301 处理;若清除后 CDN 仍返回 200,则要检查 CDN 的回源规则是否指向了另一个源站,或者是否存在独立的边缘缓存规则覆盖了清除操作。

这个例子的数字仅为说明比较方法,不代表任何真实项目的表现。

哪些例外会让上述判断失效

有几种情况不能简单套用上面的结论。第一,站点使用多源站或灰度发布,不同源站本身返回不同状态,此时缓存只是暴露了源站分歧。第二,检查工具自身带缓存或遵循了 robots.txt 限制,导致部分请求根本没有到达目标层;抓取限制不等于索引移除,检查结果缺失也不能直接当作链接正常。第三,站点启用了按地区或设备返回不同内容的规则,不同节点命中不同逻辑,状态码差异未必来自缓存。

遇到这些例外,先确认检查请求是否真正到达了你想测的那一层,再决定是修缓存、修源站逻辑,还是调整检查方法。只有在确认请求路径和缓存键都一致之后,状态码的差异才适合被当作死链证据使用。

图1 图2

nginx