CDN 缓存不更新怎么办?缓存键、回源与版本号排查

2026-09-19

直接答案:CDN 显示旧内容时,先区分旧内容来自浏览器缓存、Service Worker、CDN 边缘节点、源站 Nginx/FastCGI 缓存、应用页面缓存还是数据库。然后对同一 URL 记录响应体摘要、Cache-Control、Age、ETag、Last-Modified、CDN 缓存状态和命中节点。在哪一层第一次出现旧版本,就修哪一层。直接执行全站 Purge 会增加回源压力,也无法修复错误的缓存规则。

缓存问题最容易被“我这里已经新了”误判。不同地区、不同查询参数、登录状态、设备和 CDN 节点可能使用不同缓存键。验收必须从多个网络和无登录会话进行,并与源站直连结果对照。

六层缓存地图

层级 常见标志 如何旁路或验证 典型根因
浏览器内存/磁盘 DevTools 显示 memory/disk cache 无痕窗口、禁用缓存、改版本 URL 本地缓存未过期
Service Worker 请求被 Worker 接管 查看 Application/Service Workers 离线策略未更新
CDN 边缘 Age、供应商缓存状态头 指定节点/地区、Purge 单 URL TTL、缓存键、节点传播
源站代理 Nginx/FastCGI 缓存头或目录 直连源站、查缓存日志 源站仍缓存旧响应
应用缓存 插件、页面缓存、Redis 应用调试、按 key 清理 缓存失效逻辑错误
数据层 API/数据库本身旧 直接查询权威数据源 更新未提交、读副本延迟

第一步:给新旧版本一个可验证标记

不要凭肉眼比较整页。为测试版本记录构建号、发布时间或内容哈希,并选择一个具体 URL。响应体可以计算摘要;静态文件可在文件名中使用内容哈希。这样能回答“哪个节点返回哪个版本”,而不是争论页面看起来是否变化。

测试时保存时间、URL、查询参数、Cookie 状态、客户端地区、解析到的 CDN、响应头和摘要。涉及个性化页面时要保护 Cookie 和用户信息,不把授权响应拿去公开测试。

第二步:读取缓存响应头

Cache-Control 决定浏览器和共享缓存的基本行为,Age 表示响应在共享缓存中的驻留秒数,ETag 与 Last-Modified 可参与重新验证。CDN 还会增加自己的 HIT/MISS/BYPASS/DYNAMIC 等状态头,具体含义以供应商文档为准。

常见误区包括:

  • HTML 设置了很长 max-age,发布后用户浏览器仍持有旧页;
  • 只设置浏览器 no-cache,但 CDN 页面规则覆盖了源站;
  • Set-Cookie、Authorization 或自定义规则导致本应缓存的静态资源 BYPASS;
  • 查询参数被忽略,不同版本 URL 落到同一个缓存键;
  • 查询参数全部进入缓存键,制造大量碎片并使 Purge 漏掉变体;
  • 源站返回旧内容,CDN 正确地缓存了“旧的源站结果”。

第三步:比较边缘与源站

在不绕过 TLS 和 Host 校验的前提下直连源站,带正确 Host 请求同一 URL。若源站已新而边缘旧,问题在 CDN 缓存或刷新传播;若源站也旧,应继续查 Nginx、应用、Redis 和数据库。不要通过公开源站 IP 长期绕过 CDN,这会暴露攻击面。

CDN 与源站的职责可参考CDN 和云服务器的区别。源站 IP 防护和回源规则改变前,应保留上一版配置与访问方式。

静态资源优先用版本化,而不是频繁清缓存

CSS、JS、图片等内容变化时,使用内容哈希或构建版本文件名,例如 app.内容哈希.js。HTML 可较短缓存或重新验证,并引用新文件名。这样旧 HTML 仍能找到旧资源,新 HTML 指向新资源,发布和回滚都更可控。

仅在文件名不变时依赖查询参数,也要确认 CDN 缓存键是否包含该参数。不要把随机时间戳加到每次访问,长期会破坏缓存命中并增加回源。

HTML、API 与登录页面怎样设置

公开且变化不频繁的 HTML 可以设置短 TTL 和重新验证;强时效页要根据业务缩短。含账号、订单、购物车或个性化数据的响应通常不应进入共享缓存,需正确使用 private、no-store 或供应商绕过规则。API 是否缓存取决于方法、认证、数据时效和幂等性,不能用一条全站规则覆盖。

no-cache 的语义是使用前重新验证,不等于“完全不存储”;no-store 才是要求不存储。错误理解会造成一边以为关闭缓存、一边仍看到条件请求。

Purge 怎样做才安全

优先按精确 URL 或标签清理,而不是全站。清理前确认缓存键包含的主机、路径、查询参数、协议和设备维度;否则可能只清掉一个变体。全站 Purge 会在热门站点形成回源洪峰,应提前确认源站容量和限流。

发布失败时,版本化资源可以把 HTML 引用切回上一构建;若已 Purge,应确保旧构建文件仍存在。不要在回滚前删除所有旧静态资源。

一套可重复的验收表

  1. 源站返回新版本摘要和正确缓存头。
  2. 至少两个地区/运营商的边缘节点返回新版本。
  3. HIT/MISS、Age 与预期 TTL 一致。
  4. 无痕窗口和普通窗口都能按策略更新。
  5. 登录、购物车、订单等私有页面没有被共享缓存。
  6. 404、重定向和 API 错误没有被异常长时间缓存。
  7. 回源请求、带宽和 5xx 未因刷新出现尖峰。

若缓存故障来自源站性能不足,可结合云服务器监控告警指南和服务器 502/504 排查。需要隔离环境复现回源与版本发布时,可查看美国轻量云或美国弹性云服务器的实时配置。

常见问题

清了 CDN 缓存为什么浏览器还是旧内容?

浏览器、Service Worker、源站代理或应用缓存仍可能保存旧版本。用无痕、禁用缓存和响应摘要分层验证。

Age: 0 就是没有缓存吗?

不一定。可能是刚进入共享缓存或被重新验证。还要结合供应商缓存状态头、后续请求和源站日志。

no-cache 和 no-store 一样吗?

不一样。no-cache 允许存储但使用前应重新验证,no-store 要求不存储响应。

全站 Purge 能作为每次发布步骤吗?

不推荐。它会降低命中并增加回源风险。静态文件版本化、精确 URL/标签清理更可控。

CDN 多久会在所有节点更新?

取决于供应商、刷新方式、节点和缓存键。不能只看控制台“成功”,应从目标地区读取响应头和版本摘要验收。

官方参考资料

最近更新