
同一个 CDN 地址,有些用户看到新内容,有些用户却仍然拿到旧页面或旧脚本,未必是 CDN 节点“坏了”。更常见的原因是请求落到了不同节点、缓存键不一致、发布时只刷新了部分对象,或者上层缓存仍保留旧版本。
排查时要回答三个问题:用户请求是否命中了同一个缓存对象,缓存对象是否已经过期或被刷新,以及不同层级的缓存是否都拿到了同一版本。只看一个地区或一次 curl 结果,通常不足以判断全局状态。
先确认差异来自哪里
找一个能明确识别版本的资源,例如带内容哈希的 JS 文件、响应中的版本号,或测试页面中短暂展示的构建标识。记录请求时间、解析到的边缘 IP、响应头、缓存状态、Age、ETag 和资源内容摘要。不要把用户 Cookie、签名参数或完整授权链接直接发到公共工单里。
从多个网络和地区重复请求同一个 URL,并保持请求方法、Host、协议和请求头一致。若只有某个运营商或某个地区持续拿到旧内容,优先检查 DNS 调度、节点缓存和发布传播;若同一地区在短时间内随机变化,重点检查缓存键、分层缓存或多个源站版本。
缓存键不同,刷新一个对象也不够
CDN 可能根据查询字符串、指定 Cookie、请求头、Host 或路径规则生成缓存键。两个看起来相同的 URL,如果携带的查询参数顺序、语言标识或设备相关 Cookie 不同,实际可能对应不同缓存对象。
先把异常请求按以下维度分组:
完整 URL 与查询参数是否相同;
Host、协议和端口是否一致;是否带有会进入缓存键的 Cookie 或请求头;
大小写、尾部斜杠和 URL 编码是否被规则统一;
页面、脚本和 API 是否使用了不同的缓存行为。
不要为了“统一命中”而把登录态、购物车状态或权限相关参数从缓存键里删除。公用缓存键设计错误可能把一个用户的响应提供给另一个用户,安全风险比旧内容更严重。
版本化资源比全站刷新更容易验证
静态脚本和样式表适合使用内容哈希或明确版本号的文件名,例如 app.7f3a1c.js。新版本发布后让 HTML 引用新文件,旧文件可以保留一段时间,避免仍在使用旧 HTML 的客户端立即得到 404。
如果必须复用同一个 URL,先确认 CDN 的失效范围、执行结果和完成时间。精确刷新目标对象通常比全站清缓存更容易控制影响,但刷新并不一定覆盖浏览器缓存、Service Worker、上层缓存或其他域名。发布记录应包含对象路径、版本标识、刷新请求 ID 和验证时间。
分层缓存会放大版本传播差异
使用多层缓存时,边缘节点未命中后可能从上层缓存取得对象。边缘节点已经刷新,并不代表上层缓存一定已更新;相反,上层缓存持有旧对象时,多个边缘节点可能重新得到同一份旧内容。
核对 CDN 产品对上层缓存、请求合并、失效传播和 Age 的定义。Age 只能说明当前响应在某个缓存链路中的年龄,不能单独证明所有节点都使用同一版本。不同节点返回不同的缓存状态,也不能直接推断源站被请求了多少次。
若 CDN 支持回源响应头或请求追踪 ID,给测试请求保留这些信息。源站日志也应记录资源版本、Host、请求时间和 CDN 注入的追踪标识,方便把一次用户请求和一次回源对应起来。
源站不一致也会伪装成 CDN 缓存问题
同一个缓存对象如果在不同时间从不同源站填充,用户仍可能看到不同版本。检查负载均衡后的源站、对象存储副本、发布目录和容器镜像是否完成同步。
对静态资源生成 SHA-256 摘要,在各源站和对象存储端分别核对。对 HTML 或 API 响应,用构建 ID 或后端版本标识比较,不要只凭页面视觉判断。测试时使用只读请求,避免用带副作用的接口验证发布状态。
如果源站刚完成发布,先确认所有回源目标都已经具备新资源,再执行 CDN 刷新。否则,刷新动作可能把不同源站的版本重新填充到不同节点,问题会反复出现。
一组安全的排查命令
下面的示例只读取公开的小型静态文件,并把响应头和内容保存到临时目录。替换为自己的域名和路径,不要使用生产账号或私有下载链接。
for i in 1 2 3; do curl -sS --max-time 10 \ -D "headers-$i.txt" -o "body-$i.txt" \ 'https://cdn.example.com/assets/app.7f3a1c.js' sha256sum "body-$i.txt" done
比较不同网络环境下的响应头和摘要。若要比较边缘节点,记录 DNS 解析结果,但不要仅凭 IP 地址判断节点身份;服务商可能使用 Anycast 或动态调度。
按影响范围修复
如果只有旧 URL 受影响,优先改为版本化资源,并保留旧文件一段兼容时间。如果是缓存键过度区分,减少无业务意义的变化项;如果是缓存键过度合并,先恢复隔离,再评估哪些响应可以公开缓存。
如果确认上层缓存或失效传播存在延迟,把发布流程改成“源站全部就绪—验证源站版本—刷新精确对象—多地区验证”。不要在未确认源站状态前反复全站刷新,这只能增加回源压力,不能修复错误的缓存键。
每次只变更一个规则或一个资源组,保存旧配置和回滚方式。验收至少覆盖两个网络、两个时间点,并同时核对响应内容、缓存状态、错误率和源站请求量。发布完成的标准不是某一次请求返回新内容,而是可重复地得到预期版本。
参考资料
资料核验日期:2026 年 11 月 9 日。本文中的命令是受控读取示例,不代表已在读者的生产环境执行。