先给结论:当同一批链接在多层缓存下出现不同状态时,不要从最外层开始逐层清缓存,而应先用一个带唯一标记的测试链接,确认各层缓存各自返回的是哪个版本,再判断不一致发生在哪一层的键值或失效逻辑上。定位顺序是:固定请求路径→标记来源→比较版本→只改一层→复测。
以下情境为假设,用于说明决策过程:某站有CDN、反向代理缓存、应用层对象缓存三层。抽样检查时,A链接在CDN返回404、在代理返回200、在源站返回200;B链接三层都返回404,但源站实际存在。团队最初打算批量清缓存,结果清完后A在CDN仍返回404,B在代理层变成200,问题从“部分不一致”变成“随机不一致”。这个反例说明:不一致不是缓存脏,而是各层对同一请求使用了不同的键或不同的失效触发条件。
多层缓存返回不同版本,最常见的原因是请求在到达源站前被改写。需要先固定三件事:请求的完整URL(含查询串和结尾斜杠)、请求方法、以及请求头中影响缓存键的字段。假设CDN按“完整URL+设备类型”做键,代理只按“路径”做键,那么同一路径带不同查询串时,代理会命中同一份缓存,CDN则分开存储。此时看到的“不同版本”其实是不同缓存键各自命中了不同时间的副本。
可执行动作:给测试链接加一个不会影响业务的唯一查询参数,例如 ?probe=20240601a,然后分别直接请求源站、代理层和CDN层,记录每层返回的状态码、响应头中的缓存标识和响应体中的版本标记。结果如何影响下一步:如果三层返回的版本标记不同,说明键不一致;如果版本标记相同但状态码不同,说明状态码被某一层改写或拦截。只有先分清这两种情况,后续修改才不至于把键问题当成失效问题处理。
这两类不一致的处理方式不同。缓存旧版本,通常表现为源站已是200,但某层仍返回旧内容或旧重定向;缓存错误状态码,则表现为源站200,某层返回404或410,且响应头里可能带有该层自己的缓存命中标记。可区分证据是:对同一URL追加唯一查询参数后再次请求,如果状态码恢复正常,说明问题出在旧缓存条目;如果仍返回错误状态码,说明该层在回源前就做了判断,例如按规则拦截、按本地配置返回,或把上游的某次错误结果缓存了下来。
假设例子:代理层配置了“回源超时即缓存404若干秒”,源站偶发超时后,代理把404写进缓存,CDN随后回源到代理,也拿到404并缓存。此时源站一直正常,但外层持续返回404。这个链条的起点不是死链接,而是超时后的错误缓存策略。若只清CDN,代理层仍会再次把404喂给CDN;若只清代理,CDN手里的旧404仍会在其缓存期内继续返回。因此必须按“谁先产生该状态码”的顺序处理。
定位到疑似层后,每次只改一个变量,并立即复测三层。可参考下面的顺序:
结果如何影响下一步:如果清掉代理层后,CDN仍返回旧状态,说明CDN缓存期未到或CDN有自己的键规则,需要继续在CDN层验证;如果清掉CDN后恢复正常,但过一段时间又复现,说明代理层仍在产生可被缓存的错误状态,必须回到代理层的回源和错误缓存配置。只清最外层而不查内层,往往会在缓存期结束后再次复现。
抽样时选中的链接往往路径简单、查询串少、命中规则单一,因此三层容易表现一致。规模化后出现例外,通常是因为以下条件发生了变化:URL带上了追踪参数、大小写或结尾斜杠不统一;部分链接被规则改写或重定向;不同层对某些状态码的缓存策略不同;某些请求命中了预热缓存或旧缓存。这些条件下,抽样结论不能直接照搬到全站。
要判断例外是否属于同一类问题,可以按“路径特征+查询串特征+首次发现层”分组,而不是按链接总数平均抽样。假设全站一万条链接中,只有带特定查询参数的链接在CDN层返回404,而其他链接正常,那么问题更可能出在CDN的缓存键或参数处理规则,而不是源站链接本身。此时正确的下一步是拿同组内多条链接复测,确认是否同一规则导致,而不是继续扩大随机抽样。
还要注意:robots.txt 的抓取限制不等于可靠的索引移除,站点地图不保证收录,HTTPS 不保证安全无漏洞或排名。这些事实与缓存不一致的定位有关,因为外层返回的状态可能受抓取规则、重定向和安全层拦截影响;看到404或异常状态时,不能只凭单一层的返回就断定链接已死。请求量、抓取量或某项统计归零也不能单独证明处理正确,它还可能来自缓存命中变化、规则调整或采集端行为变化。
最终要留下的不是“已清缓存”,而是一组可复查记录:测试URL、唯一标记、请求层、返回状态码、缓存标识、版本标记、修改动作和复测结果。这样做的实际作用是,当问题再次出现时,可以判断是同一层同一规则复发,还是另一层产生了新的错误缓存。若三层返回一致但状态仍不符合预期,问题就不在缓存一致性,而应转向源站内容、重定向规则或访问控制配置。定位一致性问题,核心是让每一层都留下可比较的版本证据,而不是靠清缓存碰运气。