No.87
CDN 的原理是什么?
一句话回答
CDN(内容分发网络)把内容缓存到离用户更近的边缘节点,让用户就近访问,既降低延迟,也减轻源站压力。核心是两件事:调度,域名用 CNAME 接入 CDN,由 CDN 的智能 DNS 按用户位置、运营商和节点负载返回最合适的节点 IP;缓存,边缘节点有未过期的缓存就直接返回,没有就回源拉取并缓存下来。
详细解析
访问流程
文本
用户请求 https://static.example.com/app.3f9a1c.js
│
├─ 1. DNS 解析 static.example.com
│ 权威 DNS 返回 CNAME:static.example.com.cdn.example.net(CDN 厂商分配的域名)
│
├─ 2. 继续解析这个 CNAME,由 CDN 的调度系统(智能 DNS / GSLB)应答
│ 综合用户位置、运营商、节点负载和健康状况,返回最合适的边缘节点 IP
│
├─ 3. 浏览器向这个边缘节点发起请求
│
└─ 4. 边缘节点查缓存
├─ 命中且未过期 → 直接返回
└─ 未命中或已过期 → 回源(可能先经过中间层节点)→ 拿到内容,按规则缓存后返回
DNS 的解析过程见 DNS 解析。除了 DNS 调度,有的 CDN 还会结合 Anycast:多个节点对外宣告同一个 IP,由网络路由把用户送到最近的节点。
缓存规则
- 默认通常遵循源站返回的
Cache-Control等响应头(见 HTTP 缓存)。s-maxage只对 CDN 这类共享缓存生效,并且优先于max-age,可以让 CDN 和浏览器缓存不同的时长;private、no-store的响应不应该被 CDN 缓存 - 也可以在 CDN 控制台按路径或文件后缀配置缓存时间,它和源站响应头哪个优先,取决于厂商和具体配置
- 缓存键决定哪些请求共用同一份缓存,一般由域名和路径组成,查询参数是否计入可以配置:
- 计入参数:
utm_source这类无关参数、随机时间戳都会生成新的缓存,命中率下降,回源增多 - 忽略参数:命中率高,但如果参数会影响返回内容(比如图片处理参数
?w=200),就会返回错误的内容
- 计入参数:
内容更新:刷新和预热
| 操作 | 作用 | 适用场景 |
|---|---|---|
| 刷新(purge) | 让节点上的缓存失效,下次请求时回源拉取 | URL 不变但内容变了,比如紧急替换了一张图片 |
| 预热 | 提前把资源推送到节点,用户第一次访问就能命中 | 大版本发布、安装包或视频上线前,避免大量请求同时回源 |
刷新是异步的,全网生效需要一段时间,通常还有次数或频率限制;大范围刷新后,请求会集中回源,要关注源站的压力。
最佳实践:hash 文件名 + 长期缓存
- JS、CSS、图片等静态资源的文件名带上内容 hash(如
app.3f9a1c.js),设置长期缓存:Cache-Control: max-age=31536000, immutable - 发布新版本时内容变了,文件名跟着变,CDN 和浏览器会把它当作新资源来请求,自然绕过了旧缓存,不需要刷新
- HTML 是入口,不缓存或只短时间缓存,保证用户能拿到引用新文件名的 HTML
- 发布时先上传新的静态资源,再更新 HTML;旧版本的资源保留一段时间,避免还停留在旧页面的用户加载旧文件失败
其他能力
- HTTPS:在 CDN 上托管证书,用户和边缘节点之间走 HTTPS
- 防盗链:校验
Referer白名单,但Referer可能为空,也可能被伪造,只能挡住普通的盗链;更严格的是 URL 签名鉴权,URL 里带上过期时间和用密钥算出的签名,CDN 校验通过才返回 - 安全防护:大量节点分散承接流量,提供 DDoS 防护,也能隐藏源站 IP
- 动态加速:接口这类动态内容不能缓存,CDN 通过智能选路找到更快的回源路径,降低跨地区、跨运营商访问的延迟
常见问题
- 发布后用户拿到旧资源:见下面的追问
- 大量请求未命中缓存,回源压力过大:常见原因有缓存时间太短、缓存键里带了随机参数、大范围刷新、源站返回了不允许缓存的响应头。处理办法:合理设置缓存时间,忽略无关参数,提前预热,利用中间层节点收敛回源请求,源站做好限流
面试官可能追问
怎么判断请求有没有命中 CDN 缓存?
看响应头,具体字段因厂商而异:
Age:响应在缓存里已经存放了多少秒,大于 0 一般说明来自缓存- 厂商自定义的头,比如
X-Cache(值类似HIT、MISS)、Cloudflare 的CF-Cache-Status
用 curl -I 连续请求两次,对比响应头最直观。整体命中率可以在 CDN 控制台的统计数据里看。
发布后用户还拿到旧文件,怎么办?
先找原因:
- HTML 被缓存了(在 CDN 或浏览器上),拿到的是引用旧文件名的旧 HTML → HTML 改成
no-cache或短缓存 - 资源内容变了,但文件名没变 → 改成带 hash 的文件名
- 临时处理:在 CDN 控制台刷新对应的 URL 或目录
刷新只能清掉 CDN 节点上的缓存。用户浏览器里已经强缓存的文件,服务端通常没办法主动让它失效,只能等它过期,所以 HTML 从一开始就不能设置长缓存。
CDN 出故障了怎么办?
- 多 CDN 容灾:同一个域名接入多家 CDN,通过 DNS 按权重或地区分配,一家出问题就切到另一家
- 切回源站:把域名解析改回源站,前提是源站扛得住全部流量;DNS 记录有 TTL,切换不会立刻生效
- 前端兜底:资源加载失败时,换一个备用域名重试
易错点
- CDN 不只是"缓存静态文件",就近调度同样是核心;动态接口也能用 CDN 加速,只是不缓存,只优化链路
- DNS 调度时,调度系统看到的通常是本地 DNS 服务器的 IP,而不是用户的 IP。用户用了异地的公共 DNS 时,可能被调度到不合适的节点;EDNS Client Subnet(ECS)可以把用户的网段告诉权威 DNS,缓解这个问题
AI 模拟面试官
用自己的话回答,AI 对照参考答案打分、指出遗漏,再追问,最多 3 轮
登录后就可以和 AI 面试官对练,面试记录也会保存下来。登录
这道题你掌握了吗?
选一个最接近的状态,没掌握的题会出现在"我的进度 · 待复习"里。
学习记录暂存在本机浏览器。登录后自动同步到账号,换设备也能看到。