先直接回答:不要从最外层缓存开始清,而要用一个带唯一标记的请求,从浏览器到源站逐层比对响应头和响应体,找到第一层开始返回旧内容的边界。这个边界通常就是不一致的源头,后续的保留、改写或退出决策都应以它为准,而不是以你最后一次刷新看到的页面为准。
多层缓存下的死链处理,目标不是让所有层同时立刻变新,而是让“对外可见的版本”和“你决定保留的版本”一致。旧内容、旧系统或旧合作关系退出时,常见三种取舍:
三种取舍对缓存一致性的要求不同。保留和改写要求各层最终收敛到同一版本;退出则要求各层都不再返回旧内容,而不是只让某一层返回失效状态。
假设源站在页面里输出一个本次发布才有的标记,例如在 HTML 注释中写入 <!-- build-2024-a -->。用同一个 URL 依次请求:浏览器、CDN 边缘、反向代理、应用缓存、源站。每一步都记录响应头中的缓存相关字段和响应体中的标记。
判断规则很简单:第一层开始出现旧标记的位置,就是不一致的边界。如果浏览器和 CDN 都是新标记,反向代理是旧标记,那么问题在反向代理及其下游;如果源站本身就是旧标记,那问题不在缓存层,而在发布流程或数据源。
这个动作的结果会直接决定下一步:边界在 CDN,就检查该 URL 的缓存键和刷新范围;边界在反向代理,就检查它的缓存规则是否按路径、查询串或 Cookie 区分版本;边界在源站,就停止清缓存,转去核对发布是否真的生效。
看到不同版本时,不要立刻归因于“缓存没刷新”。以下原因都会产生类似现象:
可以用一个简单对照来缩小范围:同一 URL 加一个无意义查询参数再请求。如果加参数后各层都返回新版本,说明缓存键很可能忽略了查询串;如果仍然不一致,问题更可能在发布或回源环节。
选择保留的前提是内容仍然准确、外部链接仍有价值。此时要验证的是各层最终是否收敛到同一版本,而不是某一刻是否全部同时更新。可以接受短暂不一致,但不能接受某一层长期固定返回旧版本。
选择改写的前提是原链接有保留价值但目标已变。除了缓存一致性,还要验证改写后的页面是否真的对应原链接意图,避免把旧链接统一导向一个无关页面。缓存层面要确认旧版本不会被继续提供给用户。
选择退出的前提是内容确已失效且没有合适替代。此时要确认各层不再返回旧内容,同时返回的状态对用户和抓取方都是一致的。需要注意,robots.txt 的抓取限制不等于可靠的索引移除,站点地图也不保证收录;如果目标是让旧内容退出索引,仅靠缓存刷新或抓取限制都不够,需要结合具体搜索引擎的支持情况分别核查。
如果逐层比对后所有层都返回新版本,但用户仍看到旧内容,那么问题不在服务端缓存链,应转向客户端缓存、DNS 或用户本地环境排查。这个结论本身就是下一步动作的依据:不再重复刷新服务端缓存,而是换一条排查路径。