先给有条件结论:如果同一批 URL 在不同网络、不同入口下返回的跳转状态码或目标地址不一致,而源站直连测试稳定,问题大概率出在 CDN、反向代理或浏览器之间的缓存键与缓存层级差异,而不是 301 规则本身写错。这个结论成立的前提是:你能从源站直接复现唯一的跳转结果。若源站直连也返回多个版本,则应先回到应用层排查,缓存只是放大器。
多层缓存下的不一致,最常见的误判是把缓存问题当成规则问题。定位顺序应当是自下而上:
Location 头和响应体是否一致。这个顺序的价值在于:它能让你在几步内排除掉一大半无关变量。跳过源站直连直接怀疑 CDN,往往会在错误的层反复清缓存,却始终无法收敛。
多层缓存各自维护缓存键。当缓存键包含的维度不一致时,同一逻辑 URL 可能被存成多个副本,分别对应不同的跳转结果。常见的分裂维度包括:
Accept-Language、User-Agent、Cookie 是否参与缓存键,各层策略可能不同。判断方法很直接:对同一 URL 逐项改变上述维度,观察返回的跳转目标是否随之改变。若改变某一维度后结果发生跳变,该维度就是分裂来源。这一步能给出可区分原因的证据,而不是停留在猜测。
上面的“源站稳定即缓存问题”有一个明确反例:源站稳定,但缓存层对跳转响应做了改写或合并。例如 CDN 出于性能考虑,把带查询串的请求归一化到无查询串的缓存键,此时源站返回的唯一结果在边缘被复用到了本不该命中的请求上。这种情况下,源站直连永远正常,而边缘始终不一致,且清缓存只能短暂缓解。
识别信号是:不一致只出现在特定边缘节点或特定地区,且与查询串、请求头高度相关;源站日志里看不到对应的重复请求。此时要修的是缓存键策略或跳转响应的缓存规则,而不是 301 规则。
假设某路径在直连源站时固定返回 301 到带斜杠版本,但通过 CDN 访问时,有时返回 301 到不带斜杠版本。按下面的动作推进:
Location。动作的结果会直接决定下一步:如果修正缓存键后分叉消失,说明问题是缓存键设计;如果分叉仍在但范围缩小,说明还有一层未被覆盖,需要继续向源站方向排查。只有当所有维度组合都返回同一跳转目标时,才可以把该路径视为一致。
清缓存后短时间内结果一致,不能单独证明问题已解决,因为缓存未命中时所有请求都会回源,一致是暂时的。同样,某个节点恢复正常也不代表全局恢复。可靠的复查方式是:在缓存已预热的前提下,重复上述维度采样,并覆盖多个边缘节点或出口。只有当预热后仍保持唯一跳转结果,才能认为一致性成立。
把源站直连作为基准,把缓存键差异作为首要怀疑对象,再用维度采样把分叉点定位到具体一层,这套顺序能让你在多层缓存下少走弯路。