先给结论:多层缓存下出现不同版本,不要从“清缓存”开始,而要先确定哪一层在给谁返回哪一版。定位一致性问题的核心动作是固定一个可复现的请求,逐层比对响应头、正文和缓存键,直到找到第一个与源站不一致的层。只有确认了分歧层,才谈得上保留、改写或退出某层缓存。
多层缓存通常包括浏览器缓存、CDN 边缘节点、反向代理或页面缓存、应用层对象缓存,以及数据库查询缓存。它们返回不同版本,可能表现为三种情况:
Last-Modified、ETag、Cache-Control 或 Vary 不一致。这三种情况的处理方向完全不同。内容不同往往指向失效逻辑;元数据不同往往指向缓存策略;缓存键不同则常被误判为“缓存没刷新”,实际是请求从一开始就命中了另一个键。
假设某商品页在源站显示新价格,但部分用户仍看到旧价格。可以按下面的顺序做一次最小化复现:
这个动作的结果决定下一步:如果源站本身已是旧版本,问题不在缓存,而在发布或数据写入;如果源站是新版本、某一层是旧版本,则问题锁定在该层的失效或键设计上。没有这一步,任何“清缓存”都可能只是暂时掩盖分歧。
确认分歧层后,处理方式并非只有“清掉”。
适用前提是:该层缓存确实带来收益,且不同版本本应共存。例如按语言或登录态区分内容时,问题常出在 Vary 未覆盖某个请求头,导致 A 版本被返回给 B 场景。此时保留缓存、补齐键维度,比直接关闭更合理。动作是调整键或 Vary,再重复固定请求验证是否命中正确条目。
适用前提是:缓存键正确,但内容更新后旧条目没有被及时替换。常见原因是只清了边缘节点,未清反向代理;或只依赖 TTL,未在发布时主动失效。动作是让发布流程同时触发各层失效,并用同一固定请求确认每层都返回新版本。若只清一层就观察“部分用户已恢复”,不能证明其余层也已一致。
适用前提是:这一层无法可靠区分版本,且其收益低于不一致带来的风险。例如强登录态、实时价格或高频变更区域,若键设计长期无法覆盖,退出比反复修补更可控。退出后仍需检查上游是否还有缓存,否则只是把问题推给下一层。
定位过程中常看到某些指标下降或抓取量归零,但这些现象不能单独证明处理正确。抓取量归零还可能来自 robots.txt 限制、站点地图未被采用、服务器临时不可达或日志采样变化。robots.txt 的抓取限制不等于可靠的索引移除,站点地图也不保证收录。要区分“缓存已一致”和“外部表现暂时变化”,前者应由固定请求逐层验证,后者只是旁证。
同理,HTTPS 不保证安全无漏洞或排名,它只是传输层条件之一。把它当作一致性问题的主因,容易偏离真正的缓存分歧层。
一次有效的定位,最终应留下四样东西:固定请求样本、源站基准响应、各层响应比对、首个不一致层及其判定依据。这样开发或运维接手时,不需要重新猜测“到底是哪层缓存”。
如果首个不一致层是缓存键,下一步是改键并复测;如果是失效逻辑,下一步是补失效并复测;如果该层无法可靠区分版本,下一步才是评估退出。顺序颠倒,就会在错误层上反复清缓存,而真正返回旧版本的层始终没有被验证。