先给有条件的结论:只有当你能证明“同一请求在不同层被改写或命中不同对象”时,才值得按缓存一致性去排查;如果各层返回的404状态码和响应体完全一致,只是日志时间或统计口径不同,问题更可能出在观测环节,而不是缓存本身。对404页面SEO而言,真正影响判断的是状态码、响应头和最终内容这三者是否在每一层都指向同一个结果。
多层缓存通常指浏览器、CDN或反向代理、应用内对象缓存这几类组合。它们对404的处理方式并不相同:有的会缓存404并设置较短过期时间,有的只缓存200,有的会把源站的404替换成自定义错误页。你要定位的是“哪一层返回了与源站不同的版本”,而不是笼统地问“缓存有没有问题”。
可区分的原因有三类。第一类是状态码不一致:源站返回404,边缘层返回200的错误页。第二类是内容不一致:状态码都是404,但一层是默认服务器页,另一层是站点自定义页。第三类是缓存键不一致:带与不带尾斜杠、带与不带查询参数被当成不同对象,导致部分请求命中旧结果。三类的下一步动作不同,混在一起排查只会反复清缓存。
不要在多台机器上同时刷新页面。选一个已知应返回404的地址,用同一请求分别打到源站和每一层缓存入口,记录四项:HTTP状态码、Cache-Control与Age等缓存响应头、响应体首段内容、返回该结果的层标识。假设一个短例子:源站返回404且带Cache-Control: no-store,CDN入口却返回200并带Age: 3600,这说明边缘层缓存了一个与源站策略相矛盾的版本,而不是源站状态码写错。
这个动作的结果会直接决定下一步。如果只有边缘层状态码被改写,就去查该层的错误页替换规则;如果各层状态码一致而内容不同,就去查自定义错误页的部署是否只更新了部分节点;如果只有带查询参数的请求不一致,就去核对缓存键的配置,而不是继续清空整站缓存。
一个常见反例是:各层返回的404看起来不同,其实差异来自请求本身。例如测试时一层用了HEAD、另一层用了GET,或者一层带了Cookie、另一层没带,源站可能因此走了不同分支。这种情况下清缓存不会改变结果,应该先统一请求方法、请求头和参数再比较。
另一个反例是把统计归零当成修复证据。某层404日志突然减少,可能是该层开始把404替换成200,也可能是抓取量本身下降、日志采样变化或请求被前置规则拦截。请求量、抓取量或某项统计归零,不能单独证明缓存处理正确,必须回到状态码和响应体本身核对。
确认差异层之后,按以下顺序处理,并在每一步后重复同一组请求:
需要说明适用条件:如果站点对404本身设置了较长缓存时间,修复后旧版本可能仍会在部分节点存活一段时间,此时应比较新请求与旧请求的响应头,而不是要求所有节点立刻一致。如果业务依赖自定义404页做转化,还要确认该页面是否被错误地返回200,因为那会让后续判断失去基准。
最后一步是把这次差异写成一条可复用的检查项:同一地址、同一请求方法、逐层记录状态码与响应头。这样下次再出现“不同层返回不同版本”时,你能先判断是缓存策略冲突、部署不完整还是观测口径不同,再决定是否清缓存,而不是把清缓存当作默认动作。