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

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

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

先给结论:多层缓存下同一URL返回不同版本,通常不是“死链检查工具不准”,而是请求经过的缓存层不同,命中了不同副本。要定位一致性问题,先把“哪个URL、从哪条路径、拿到哪一版”变成可核对的记录,再逐层排除。下面以一个具体页面为对象,给出可执行的处理顺序。

先固定一个可复现的请求样本

不要一上来就全站跑检查。选一个已经出现版本不一致的URL,记录三项:完整URL(含协议、主机、路径、查询串)、请求时带的请求头(尤其是缓存相关的头)、以及你从哪个网络位置发起请求。同一个URL在不同出口、不同设备上结果不同,往往说明问题出在缓存链路而不是源站内容。

假设一个例子:某页面在办公网打开是旧版,在手机热点打开是新版。这个差异本身不是结论,而是一条线索——它提示两条路径命中了不同缓存。此时应固定同一URL、同一请求头,分别从两条路径各请求若干次,记录每次返回的状态码和响应体中一个稳定特征(例如页面里一个固定文案或版本标记)。

用响应头区分“源站版本”与“缓存副本”

判断一致性,关键不是看页面长得像不像,而是看响应头能不能把请求落到哪一层说清楚。重点看这些字段:

实际动作:对同一URL连续请求两次,第二次带上与第一次相同的请求头。如果第一次和第二次的ETag不同,或Age没有按预期增长,就说明中间有层在返回不同副本,而不是源站稳定输出同一版本。这个结果会直接决定下一步——是去查缓存键设计,还是去查源站发布流程。

分层验证:从最靠近源站的一层往外走

多层缓存常见结构是:浏览器缓存 → CDN/边缘缓存 → 反向代理缓存 → 应用层缓存 → 源站。定位一致性问题的有效顺序是从内往外,而不是从外往内。

  1. 先绕过所有缓存直接请求源站(例如用回源地址或临时关闭缓存策略的路径),确认源站本身是否只输出一个版本。如果源站就返回多个版本,问题不在缓存层。
  2. 再请求最靠近源站的那层缓存,记录响应头和版本特征。
  3. 逐层向外,每层都保持相同URL和请求头,只改变请求入口。
  4. 当某一层开始出现版本分歧,问题就在这一层及其与上一层之间。

这里有一个容易误判的点:抓取量或请求量突然归零,并不能单独证明缓存处理正确。它也可能来自抓取工具被限流、网络中断、或目标层临时不可达。要区分这些解释,需要同时看状态码、响应时间和响应头,而不是只看数量。

把缓存键和失效规则对齐,再决定改哪一层

版本分歧最常见的两个根因,是缓存键设计不一致和失效规则没覆盖全层。

缓存键方面:如果某一层把Accept-Encoding算进键、另一层不算,同一个URL就会产生压缩版和未压缩版两个副本,检查工具可能把它们当成不同页面。要核对的是各层Vary与键规则是否一致。

失效规则方面:发布新版本后,如果只清了CDN却漏了反向代理,或者只按路径清而没带查询串,旧副本就会继续被命中。此时的动作是:列出所有缓存层,逐层确认失效是按URL、按目录还是按标签触发,并验证失效后Age是否归零、ETag是否更新。

一个可操作的取舍:如果多层缓存由不同团队维护,优先统一缓存键和失效触发条件,而不是在检查工具里加更多忽略规则。忽略规则只会掩盖分歧,不会消除它。反过来,如果分歧只出现在极少数带特定查询串的URL上,且业务上这些URL不要求强一致,那么把检查范围限定在核心URL上、记录已知差异,也是成立的——前提是差异被明确记录,而不是被当成随机波动。

把结果落成可交接的记录

最后一步不是“修好了”,而是把定位过程变成别人能复现的记录。每条记录至少包含:URL、请求头、请求路径、状态码、Age、ETag、版本特征、以及该结果指向哪一层。这样下一个人不必重新猜,也能判断某个现象是缓存副本还是真实内容变更。当同一URL在不同层持续返回不同版本时,先改缓存键或失效规则,再重新分层验证,直到各层对同一请求给出可解释的一致结果。

图1 图2

nginx