先给结论:多层缓存返回不同版本,通常不是“缓存坏了”,而是各层对同一个二级域名的响应采用了不同的缓存键、TTL 或清理范围。定位时不要从最外层逐层清缓存,而要先固定一条请求路径,记录每层返回的版本标识,再判断差异来自哪一层的键设计。只有当差异能稳定复现、且与某一层的键或过期规则对应时,才值得改动该层配置;否则改完仍会在下一个请求上漂移。
多层缓存(浏览器、CDN、反向代理、应用内缓存)同时存在时,同一个二级域名可能因为请求头、查询串或 Cookie 不同而命中不同对象。定位的第一步是固定变量:同一个 URL、同一组请求头、同一出口 IP,连续请求若干次并记录每层返回的版本标识(如响应头里的内容版本、生成时间或摘要)。
如果多次请求结果一致,说明差异来自缓存键的输入不同,而不是缓存随机失效。这时应对比两次请求之间哪个输入变了:是否带了不同的 Accept-Encoding、是否附带登录 Cookie、是否命中了不同的查询串。如果多次请求结果本身就跳动,才更可能是某一层过期时间不一致或清理未覆盖全部节点。这两种原因的下一步动作完全不同,前者改键,后者改过期或清理范围。
把差异归因到具体一层,需要能区分以下三类,它们的证据和适用条件不一样:
一个假设例子:某二级域名同时经 CDN 和反向代理。发布新版本后,直接访问源站得到新版本,经 CDN 得到旧版本,经反向代理再经 CDN 又得到新版本。若源站与反向代理都标记了新版本,而 CDN 仍是旧版本,则差异更可能落在 CDN 这一层的过期或清理上;若反向代理返回旧版本而源站是新版本,则问题在反向代理的键或 TTL。这个比较方法只用于说明如何缩小范围,不代表真实环境结果。
没有版本标识时,多层缓存的问题只能靠猜。可行的做法是让每一层在响应中带上可区分的信息,例如内容生成时间、构建编号或内容摘要。注意这些标识本身也可能被缓存,所以要确认它随内容更新而变化,而不是固定值。
有了标识后,按以下顺序记录一次请求:客户端收到什么、CDN 返回什么、反向代理返回什么、源站返回什么。四者一致时,问题不在缓存层,应转向内容发布流程;四者中某一层开始出现旧值,问题就定位到该层及其上游。这个动作的价值在于把“缓存不一致”拆成可逐层验证的路径,下一步只需针对出现旧值的那一层检查键与过期设置,而不必全链路清理。
定位到问题后,处理方式取决于这个二级域名当前承担什么。如果它仍有独立价值(例如面向不同地区或不同业务的稳定入口),值得保留并修正缓存键与 TTL,让各层规则对齐;如果它只是旧系统或旧合作关系的遗留入口,且流量已可忽略,改写为跳转到主域通常比继续维护多层缓存更省事;如果它已无内容价值且不再需要对外提供,退出(停止解析或移除内容)是合理选项,但要先确认没有仍在依赖它的内部调用或外部链接。
判断依据不是请求量归零本身。请求量下降也可能来自抓取减少、监控缺失或统计口径变化,不能单独证明该二级域名已无用途。更可靠的依据是:是否还有业务方声明依赖、是否有内部服务仍指向它、以及移除后是否有可回退方案。只有在这些条件都明确后,退出才是低风险动作;否则先改写或保留,代价通常更低。
改动某一层的键或 TTL 后,验证要覆盖之前出现差异的那条请求路径,并在不同时间点重复。若差异随时间收敛,说明过期设置已对齐;若差异仍在固定节点出现,说明清理范围仍未覆盖。此时应继续缩小到具体节点或具体键,而不是扩大清理范围掩盖问题。
需要提醒的是,抓取限制、站点地图和 HTTPS 都不解决这类一致性问题:robots.txt 的抓取限制不等于可靠的索引移除,站点地图不保证收录,HTTPS 也不保证内容版本一致。多层缓存的版本差异只能通过逐层观察和键、过期、清理三方面的对齐来处理。修正后若差异消失但无法解释是哪一层变化导致的,就不能确认问题已解决,下一步仍应保留版本标识继续观察。