永久重定向:多层缓存返回不同版本时怎样定位一致性问题

📍 WDQWDWQD987AAAAA:176.9.85.184
📱 Mozilla/5.0 (compatible; QlyzeBot/1.0; +https://app.qlyze.io/bot)
🔗 /fb96ccfbcfda.html
📄

永久重定向:多层缓存返回不同版本时怎样定位一致性问题

先给结论:不要从最外层缓存开始清,而要先固定一个可复现的请求条件,再逐层比对每一跳返回的状态码与 Location。多层缓存返回不同版本,通常不是某一层配置错了,而是不同层对同一份永久重定向规则缓存了不同时间的副本。定位的关键是找到“哪一层开始出现分歧”,而不是把每一层都刷新一遍。

用假设情境说明分歧从哪里开始

假设这样一个场景(以下为虚构示例,仅用于说明方法):源站把 /old-page 永久重定向到 /new-page,中间经过 CDN 边缘缓存和反向代理两层缓存。运维把目标从 /new-page 改成 /new-page-v2 后,部分用户仍然跳到旧目标,部分用户跳到新目标。直觉会认为“缓存没刷干净”,但真正需要先确认的是:分歧出现在边缘层、代理层,还是源站本身。

如果源站已经返回新目标,而边缘层仍返回旧目标,问题就在边缘缓存;如果代理层就已经是旧目标,那么边缘层只是忠实转发了上游的旧副本。把这两者混为一谈,会导致反复刷新边缘缓存却始终无效。

固定请求条件,逐层比对返回结果

定位动作的第一步是让每次请求完全一致:同一个 URL、同一个协议、同一组请求头,最好带上一个自定义标记头,便于在日志中区分这次测试。然后用同一个请求分别打到源站、代理层和边缘层,记录每一跳的状态码和 Location 值。

  1. 直接请求源站,确认它当前返回的是哪个目标。
  2. 请求代理层,比对它的 Location 是否与源站一致。
  3. 请求边缘层,再比对一次。

这个动作的结果直接决定下一步:如果三层一致,说明当前规则已生效,之前看到的旧版本来自某个中间节点的残留;如果某一层开始偏离上游,那一层就是需要处理的对象。注意,命中缓存时返回旧值是正常现象,它证明的是缓存存在,而不是配置错误。

区分几种常见解释,避免误判

多层返回不同版本,至少有以下几种合理解释,需要用证据区分,而不是默认某一种:

判断方法很简单:给同一个 URL 加一个每次不同的查询参数,如果带参数的请求全部返回新目标,而原 URL 仍返回旧目标,那么问题更可能出在按完整 URL 键值缓存的那一层。

一个需要注意的反常点

永久重定向被缓存是设计预期,不是故障。正因为预期它长期不变,各层才会给它较长的缓存时间。所以当目标需要修改时,真正要处理的是“让所有层都接受新版本”,而不是抱怨缓存。反过来,如果某层在没有任何刷新动作的情况下自行变成新目标,反而值得检查:是不是 TTL 到期后回源拿到了新规则。

另外,抓取量或日志中某个 URL 的记录归零,不能单独证明重定向处理正确。它也可能来自抓取频率下降、robots.txt 限制、站点地图未更新等无关原因,需要结合源站日志一起看。

把结论落到可执行的下一步

定位到分歧层之后,动作要针对该层:如果分歧在边缘层,先确认刷新范围是否覆盖全部节点,再核对 TTL 设置;如果分歧在代理层,检查是否存在重复规则;如果三层一致但用户仍看到旧目标,把排查方向转向客户端缓存。每次改动后,用同一组固定请求条件重新比对三层返回,确认分歧是否消失。只有分歧消失,才能认为一致性问题被解决,而不是被暂时掩盖。

图1 图2

nginx