一句话结论先行:
阿里云 CDN 的"预热",主要作用在 L2 / 核心缓存层,并不会真正把资源预热到所有边缘节点(L1)。
因此,用户首次访问某个边缘节点时,仍然可能看到
MISS / TCP_MISS,这并不代表预热失败。
一、为什么很多人会"误解" CDN 预热?
很多开发者第一次使用 CDN 预热时,都会产生一个直觉上的理解:
我已经在控制台预热成功了,为什么用户访问还是 MISS?
甚至会怀疑:
- CDN 没生效?
- 预热是不是有 Bug?
- 是不是需要特殊配置?
其实不是 CDN 有问题,而是对 CDN 架构的理解不完整。
二、阿里云 CDN 的真实缓存分层架构
阿里云 CDN 并不是一个"单层缓存系统",而是一个典型的多级缓存架构。
1️⃣ CDN 分层结构示意
用户
↓
边缘节点(L1,城市 / 运营商级)
↓
核心节点(L2,区域级)
↓
源站(OSS / ECS / SLB)
2️⃣ 各层节点的职责
| 层级 | 作用 | 数量 | 特点 |
|---|---|---|---|
| L1 边缘节点 | 直接服务用户 | 非常多 | 离用户最近、命中率不稳定 |
| L2 核心节点 | 区域缓存中心 | 相对较少 | 稳定缓存、抗流量 |
| 源站 | 数据最终来源 | 极少 | 成本高、压力敏感 |
理解这一点,是理解"预热为什么只作用于 L2"的关键。
三、CDN 预热到底"做了什么"?
当在阿里云 CDN 控制台执行「URL 预热」时,真实发生的事情是:
- CDN 调度系统选择一批 核心节点(L2)
- L2 节点主动向源站拉取指定资源
- 资源缓存在 L2
- 控制台显示"预热成功"
❌ CDN 预热不会做的事情
- ❌ 不会遍历所有边缘节点(L1)
- ❌ 不会把资源复制到每一个城市、每一个运营商节点
- ❌ 不保证用户第一次访问一定是 HIT
如果真的要把资源同步到所有 L1,CDN 的成本将是不可控的。
四、为什么用户访问边缘节点仍然是 MISS?
这是一个完全正常、而且符合 CDN 设计预期的现象。
用户真实访问路径
用户 → 边缘节点 L1(MISS)
→ 核心节点 L2(HIT)
→ 返回用户
- L1 没有缓存 → 显示 MISS
- L2 已被预热 → 命中缓存
- 不回源(或极少回源)
📌 因此:
MISS / TCP_MISS并不等于"回源失败"或"预热无效"
五、如何理解常见的 CDN Header?
在浏览器或测速工具中,经常能看到类似信息:
X-Cache: TCP_MISS
X-Swift-Cache: MISS
常见状态含义说明
| 状态 | 含义 |
|---|---|
| MISS | 当前节点未命中 |
| TCP_MISS | 通过 TCP 向上游节点获取 |
| TCP_HIT | 上游节点命中缓存 |
| HIT | 当前节点直接命中 |
⚠️ 注意:
- Header 反映的是"当前访问节点"
- 不代表一定回源到 OSS / ECS
六、那 CDN 预热的真正价值是什么?
既然不能保证 L1 命中,那预热还有什么意义?
CDN 预热真正解决的问题
✅ 防止首批用户直接打到源站
✅ 防止突发访问击穿源站
✅ 降低第一次访问的 TTFB 波动
✅ 为后续自然访问提供稳定缓存基础
CDN 预热不是用来做的事情
❌ 保证全球所有节点立刻命中
❌ 作为版本更新的"强同步工具"
七、哪些资源适合预热?
结合 Web / Next.js 项目的实践经验,推荐如下:
✅ 强烈建议预热
- 首页 HTML
- 关键入口页面
- 公共 JS / CSS(非 hash)
- Banner 图 / 大图 / 视频封面
❌ 不建议预热
- 带 hash 的 chunk(版本更新即废)
- 用户私有资源
- 访问频率极低的文件
八、预热 + 自然访问,才是正确姿势
CDN 的设计理念是:
"核心节点兜底 + 边缘节点自然热度"
- 预热:解决第一次回源问题
- 用户访问:自动填充 L1 缓存
- 热点资源:自然形成高命中
这是 CDN 能在性能、成本、规模之间取得平衡的根本原因。
九、总结
阿里云 CDN 预热只作用于核心缓存层(L2),而非所有边缘节点(L1)。
用户首次访问某个边缘节点时仍可能 MISS,但通常会从核心节点命中,而不会直接回源。
正确理解这一点,可以避免对 CDN 命中率、预热效果产生不必要的误解。
如果正在使用 Next.js + OSS + 阿里云 CDN,建议把「预热 + TTL + 缓存分层」作为一个整体来设计,而不是单独依赖预热来解决所有问题。