网络学习(六)从零理解 CDN 内容分发网络

写在前面
日常上线静态资源、视频、大文件下载时,同事常说:「走 CDN」「CNAME 到加速域名」「回源了」「命中率太低」。
听多了容易把几件事搅在一起:
| 容易混淆的说法 | 它实际更接近什么 |
|---|---|
| DNS | 整套域名解析系统(「通讯录」):域名 ↔ 地址 |
| CNAME | DNS 里的一种资源记录:域名 → 另一个域名(别名),不直接给 IP |
| CDN | 把内容缓存在离用户更近的节点上,再按规则回源的分发网络 |
| 源站(Origin) | 真正存放/生成内容的业务服务器或对象存储 |
| CDN 节点 | 做缓存加速的那类服务器;日常常与「边缘节点」混用 |
| 边缘节点(Edge / POP) | 更广:靠近用户一侧的节点;CDN 缓存节点是其中最典型的一类 |
| 回源 | 边缘没有(或过期)时,向源站再要一份(这是 HTTP,不是 CNAME) |
| 负载均衡 VIP | 一组机器对外共用的入口 IP;CDN 常挂在 VIP「更前面」 |
一句话记:源站是仓库,CDN 是全国连锁的前置仓;用户就近取货,货不够再向总仓补。CNAME 只改通讯录里的别名指向,不负责把 HTTP 包转发出去。
本文只做概念讲解,不绑定某一家云、某一份源码;读完你应能回答:
- CDN 和「把文件放在一台公网服务器上」差在哪?
- 哪些业务适合上 CDN,哪些要谨慎?
- DNS 和 CNAME 是什么关系?CNAME 会不会「转发」请求到 CDN?
- 一次访问里,DNS、边缘、缓存、回源各自干了什么?CDN 节点和边缘节点怎么区分?
| 组件 | 角色 | 读者需要记住什么 |
|---|---|---|
| 业务域名 | 给用户记的名字 | static.example.com |
| DNS | 域名翻译系统 | 里面有 A / CNAME / MX 等多种记录 |
| CNAME | DNS 别名记录 | 把业务域名指到 CDN 加速域名;不传业务流量 |
| 边缘 / CDN 节点 | 就近响应 | 命中则不再打源站 |
| 源站 | 权威内容 | 未命中 / 动态请求才回这里 |
选型说明
加速侧:CDN 怎么落地
自建节点和买云 CDN,运维成本差一个数量级;多数业务先买、再按命中率与回源质量调参。
| 方案 | 特点 | 上手难度 | 典型场景 | 本文是否展开 |
|---|---|---|---|---|
| 云 CDN(厂商托管) | 全球/全国 POP、控制台接入 | 低 | Web 静态、点播、下载 | 原理重点:是 |
| 全站加速 / 动态加速 | 动静态分流,动态走优化链路 | 中 | HTML / API 也要加速 | 场景对照:是 |
| 自建缓存集群(Nginx/Varnish/ATS) | 灵活,但要自己铺点与调度 | 高 | 有机房与专线的大厂 | 概念提及:是 |
| 不用 CDN,源站直出 | 简单,跨地域延迟与带宽压力大 | 很低 | 内网、演示、极小流量 | 对比用:否 |
接入侧:业务怎么接到 CDN
CDN 不替代源站;它只负责「用户先打到谁、缓存多久、何时回源」。
| 方案 | 特点 | 上手难度 | 典型场景 | 本文是否展开 |
|---|---|---|---|---|
| 子域名 CNAME → 加速域名 | 最常见,源站仍用原地址 | 低 | 静态资源独立域名 | 是 |
| 主域名整站接入 | 页面与接口一并走 CDN | 中 | 官网、活动页、部分 API | 是 |
| 对象存储作源站 | 源站免运维,CDN 负责分发 | 低 | 图片、视频、安装包 | 是 |
| 客户端写死边缘 IP | 跳过调度 | 极低 | 仅排障 | 仅提醒风险 |
一、原理:CDN 到底是什么
图 1:没有 CDN 时,各地用户都打到同一源站;有 CDN 时,先就近命中边缘缓存,未命中再回源。
1.1 先分清「源站」和「边缘」
| 类型 | 放在哪里 | 用户是否直接打到它 | 内容从哪来 |
|---|---|---|---|
| 源站 | 你的机房 / 云主机 / 对象存储 | 接入 CDN 后通常不直接暴露给全网用户 | 业务自己生成或上传 |
| 边缘节点 | CDN 厂商在各地的 POP | 用户实际连接的是这里 | 缓存自源站,或按规则转发 |
可以把源站想成「总仓」:货全,但离多数客户远,出库带宽也贵。
边缘节点更像「城市前置仓」:热门货就近发,没有再向总仓要。
1.2 CDN 节点和边缘节点是一回事吗?
日常沟通里 CDN 节点 ≈ 边缘节点,多数场景可以混用;严格说范围不同:
| 名称 | 范围 | 典型职责 |
|---|---|---|
| CDN 节点 | 偏窄 | 静态/点播等资源的缓存与加速;未命中则回源 |
| 边缘节点(Edge) | 更广 | 部署在靠近用户一侧(网络拓扑边缘)的服务器总称 |
边缘节点还可以包括:边缘计算(在节点上跑代码)、边缘安全(WAF / DDoS 清洗)、5G MEC 等——它们也在「边缘」,但不一定是 CDN 缓存节点。
一句话:所有 CDN(缓存)节点都是边缘节点;边缘节点不一定是 CDN 缓存节点。
另外,「边缘」指的是网络拓扑上离用户更近(路由跳数更少、常在运营商接入侧),不是物理上「离用户几米」。
1.3 CDN 不是「神秘协议」,而是一套用法
严格说,用户浏览器发出的仍是普通 HTTP/HTTPS。特别之处在于请求被送到哪、响应能否被复用:
- 通过 DNS CNAME + GSLB,或 Anycast,把用户导到相对近的 POP;
- POP 按 缓存键(Cache Key) 查找对象;命中则直接返回;
- 未命中则 回源,把响应按
Cache-Control/ TTL 存下来,供后续用户复用。
所以 CDN 同时干三件事:就近接入、内容缓存、保护源站。缺任何一件,都不该叫完整的内容分发。
1.4 和「负载均衡 / VIP」别混
口头上有时都叫「分流」,但层次不同:
| 名称 | 常见含义 | 和 CDN 的关系 |
|---|---|---|
| VIP / 云负载均衡 | 一个地域内,入口 IP 把流量分到多台后端 | 常作为 源站入口,CDN 回源打到它 |
| CDN | 跨地域把用户导到各地边缘,并缓存内容 | 在 VIP 更靠近用户 的一侧 |
| Anycast | 多地宣告同一地址,路由选近路 | 部分 CDN 用它做接入,而不只靠 DNS |
本文说的 CDN,默认指:边缘缓存 + 调度 + 回源 这一整套,而不只是「多几台 Nginx」。
二、CDN 用在哪些场景
图 2:静态资源、点播、大文件、直播、全站加速、安全防护,是 CDN 最常见的六类用法。

2.1 场景一:静态资源加速(最经典)
CSS、JS、图片、字体、前端构建产物,同一文件会被成千上万用户反复下载。
无 CDN:每个用户都打源站 → 带宽打满、首屏随距离变慢
有 CDN:第一次回源后,后续用户在边缘命中 → 源站几乎无感
适合独立出一个静态域名(如 static.example.com),长缓存、文件名带 hash,更新靠改文件名而不是频繁刷新。
2.2 场景二:点播与大文件下载
MP4、HLS 切片、安装包、镜像,单对象体积大、重复下载多。CDN 的价值是:
| 能力 | 说明 |
|---|---|
| 就近传输 | 减少跨网跨省绕路 |
| 切片缓存 | HLS/DASH 的 .ts / .m4s 极易命中 |
| Range 请求 | 支持拖进度、断点续传 |
| 源站减负 | 避免把对象存储或机房带宽打穿 |
下载类还常配合 分片回源、一致性哈希,避免同一大文件把单台源站打爆。
2.3 场景三:直播加速
直播不能「先整段缓存再播」,但仍走 CDN:
- 推流到源站或厂商直播中心;
- 边缘做 流分发 / 短暂切片缓存;
- 用户就近拉流,降低卡顿与跨网丢包。
和点播的差别:点播吃「对象缓存」;直播吃「就近转发 + 短时切片」。
2.4 场景四:全站 / 动态加速(要谨慎用缓存)
HTML、带 Cookie 的页面、个性化 API 默认不可长缓存。这时 CDN 仍可能有用:
- 静态路径继续缓存;动态路径只做 协议栈优化、连接复用、智能路由;
- 部分接口用短 TTL 或按查询参数精细缓存。
| 内容类型 | 能否长缓存 | 建议 |
|---|---|---|
| 带 hash 的静态文件 | 能(可到年) | Cache-Control: public, max-age=... immutable |
| 活动页 HTML | 短缓存或协商缓存 | 发布后刷新 URL |
| 用户 API(含登录态) | 通常不缓存 | Bypass,或只缓存公开只读接口 |
| 验证码 / 下单 | 禁止缓存 | 明确 private, no-store |
2.5 场景五:源站保护与安全叠加
CDN 把公网流量挡在边缘,源站只对 CDN 回源 IP 开放,相当于少暴露攻击面。厂商还常叠加:
- DDoS / CC 清洗;
- WAF;
- HTTPS 证书托管、强制跳转、HTTP/2 / HTTP/3。
这些不是「缓存」本身,但是生产接入 CDN 的常见配套。
2.6 CDN 不适合什么
| 误区或反例 | 实际情况 |
|---|---|
| 「所有接口都上 CDN 就更快」 | 不可缓存的动态请求,加速有限,还可能引入缓存脏数据 |
| 「上了 CDN 源站可以随便弱」 | 未命中、刷新、突发流量仍会回源,源站要扛得住穿透 |
| 「缓存越久越好」 | 配置页、价格、库存一旦被长缓存,业务事故比慢更严重 |
| 「CDN 等于多活容灾」 | 源站挂了,未缓存的请求一样失败;要另做源站高可用 |
三、实现原理:一次请求怎么走完
图 3:用户访问域名 → DNS/CNAME → GSLB/Anycast 选近 POP → 边缘命中或回源。

3.1 先分清:DNS 是系统,CNAME 是其中一种记录
DNS(Domain Name System) 是整套域名解析系统,任务是把「名字」翻译成「怎么连」——浏览器输入域名后,先靠 DNS 查到地址,再发 HTTP。
DNS 里存放多种资源记录(RR),常见有:
| 记录类型 | 指向什么 | 典型用途 |
|---|---|---|
| A | 域名 → IPv4 | 直接落到某台/某组 IP |
| AAAA | 域名 → IPv6 | 同上(IPv6) |
| CNAME | 域名 → 另一个域名(别名) | CDN、云 LB:不直接写死 IP |
| MX | 邮件服务器 | 收信 |
| TXT | 文本 | 域名验证、SPF 等 |
| NS | 权威域名服务器 | 委派解析 |
CNAME(Canonical Name) 是 DNS 里的别名记录:把 alias(别名)指到 canonical name(规范名),这一步不返回 IP。二者不是同级概念——CNAME ⊂ DNS。
通俗比喻:
| 现实 | 对应 |
|---|---|
| 整本通讯录 | DNS |
| 「小明 → 手机号」 | A 记录 |
| 「外号阿明 → 真名小明」(再查小明的号) | CNAME |
A 记录 vs CNAME
| 类型 | 指向目标 | 适用场景 |
|---|---|---|
| A | 直接 IP | IP 相对固定的独立入口 |
| CNAME | 另一个域名 | CDN、云负载均衡、后端 IP 常变:只改目标域名的 A,所有别名跟着生效 |
配置时几条硬规则
- 同一主机名上,CNAME 一般不能与 A / MX / TXT 等其它记录并存(RFC 语义:CNAME 表示「本名字只是别名」);需要 A+MX 时,通常给根域用 A,给
www等子域用 CNAME。 - 根域名(如
example.com,apex)很多场景不适合直接 CNAME(与 SOA/NS 等冲突);CDN 常用子域www/static,或厂商提供的「根域别名」类特殊方案(以 DNS/CDN 厂商文档为准)。 - CNAME 可以再套 CNAME,但链太长会多次查询、增加延迟,生产不建议绕太深。
3.2 接入 CDN:CNAME 只改解析,不转发 HTTP
最常见挂法:
static.example.com. CNAME static.example.com.cdn.vendor.com.
static.example.com.cdn.vendor.com. → 厂商调度得到边缘 IP(A / Anycast)
你维护的是「业务域名指到厂商」;厂商维护「这个名字此刻落到哪几个边缘 IP」。
不要把业务域名直接 A 记录写成某一台边缘机 IP:节点摘除、调度变更后会指向失效地址。
易错点:CNAME 不是反向代理,也不等于「把请求转到 CDN 再转到源站」。
| 阶段 | 谁在干活 | 实际发生什么 |
|---|---|---|
| DNS 查询 | 浏览器 / 系统解析器 | 看到 CNAME → 再查加速域名 → 得到就近 CDN 节点 IP |
| HTTP(S) | 浏览器 ↔ CDN 节点 | 用户直接连边缘 IP 拉资源 |
| 回源(仅必要时) | CDN 节点 ↔ 源站 | 边缘 MISS/过期时,节点主动去源站拉,再缓存后返回用户 |
纠正两种说法:
❌ 用户 → CNAME → CDN → 源站 (把 CNAME 当成流量转发链路)
✅ 用户 --(DNS: CNAME 只帮忙找到边缘 IP)--> 连上 CDN 节点
└─ HIT:直接返回,不碰源站
└─ MISS:CDN 节点 HTTP 回源 → 源站,再返回用户
一句话:
- CNAME:DNS 别名,只管「名字翻译到哪」,不传输业务流量;
- CDN 回源:边缘与源站之间的 HTTP,和 CNAME 不是一回事。
对照:
| 接入方式 | 路径 |
|---|---|
| 不用 CDN(业务域名 A 记录) | DNS → 源站 IP → 浏览器直接请求源站 |
| 使用 CDN(业务域名 CNAME) | DNS → CNAME → CDN 域名 → 边缘 IP → 请求边缘 →(必要时)边缘回源 |
3.3 调度:凭什么说「就近」
CDN 把用户导到某个 POP,常见两条路(可并存):
| 机制 | 做法 | 特点 |
|---|---|---|
| DNS 调度(GSLB) | 根据 Local DNS 出口 IP 估用户位置,返回附近节点 A 记录 | 依赖 DNS 质量;公司 DNS 出口可能「看起来像外地」 |
| Anycast | 多地宣告同一 IP,由互联网路由选近路 | 用户连的是同一地址,实际落到不同机房 |
排障时若「明明在上海却打到北京节点」,优先查:Local DNS 是否被劫持/转发、是否用了公共 DNS、调度策略是否按运营商分流。
3.4 缓存:命中、未命中、过期
图 4:边缘按 Cache Key 查找;HIT 直接返回,MISS 回源后再按 Cache-Control 写入。

一次边缘处理可以简化成:
1. 算出 Cache Key(通常是 协议 + Host + 路径 + 你允许的查询参数)
2. 查本地缓存
- HIT:返回对象(常带 Age、X-Cache: HIT 一类头)
- MISS:回源,按响应头决定能否存、存多久
- EXPIRED:可用过期内容先回用户再异步回源(视厂商策略),或阻塞回源再返回
3. 把可缓存响应写入边缘,供下一个用户复用
能不能缓存,优先看源站响应,而不是只看控制台「默认 TTL」:
| 响应头 / 约定 | 作用 |
|---|---|
Cache-Control: public, max-age=... | 允许共享缓存存多久 |
s-maxage | 专门给 CDN 等共享缓存的 TTL,优先于 max-age |
private / no-store | 不让 CDN 存(或不应存) |
Set-Cookie | 多数 CDN 默认不缓存带 Cookie 的响应 |
Vary | 按 Accept-Encoding / Origin 等拆缓存副本 |
工程上记住一句:文件名带内容 hash + 长 TTL,比「同一个 URL 改文件再手动刷新」更稳。
3.5 回源:边缘向源站要内容
未命中时,边缘以 HTTP 客户端 身份访问源站:
用户 → 边缘 POP → 源站(或源站前面的负载均衡 VIP)
↑ 缓存
回源时要特别注意:
| 点 | 为什么重要 |
|---|---|
| 回源 Host | 源站按域名选站点/证书;填错会 404 或证书不匹配 |
| 回源协议 | HTTP 回源省开销;全站 HTTPS 时常要求 HTTPS 回源 |
| 回源鉴权 | 源站应只放行 CDN 回源 IP,避免用户绕过 CDN 直打 |
| 回源超时与重试 | 源站慢会导致边缘堆积,命中率再高也救不了穿透瞬间 |
拉取(Pull) 是主流:用户第一次访问才回源。
推送(Push) 适合超热、超大、必须提前到边缘的对象(预热),成本更高,一般不作默认。
3.6 刷新与预热
| 操作 | 做什么 | 何时用 |
|---|---|---|
| 刷新(Purge) | 让已缓存对象失效 | 紧急改了未改名的静态文件、下线违规内容 |
| 预热(Prefetch) | 主动让边缘去源站拉一份 | 大促前超热资源、超大包,避免开场回源打爆 |
刷新是「删缓存」,不是「改源站」。源站没更新就刷新,下一次回源仍是旧内容。
3.7 HTTPS 在 CDN 上怎么终结
常见两种:
| 模式 | 含义 |
|---|---|
| 边缘卸载证书 | 用户 ↔ CDN 用 HTTPS;CDN ↔ 源站可用 HTTP 或 HTTPS |
| 全链路 HTTPS | 用户到边缘、边缘到源站都加密 |
证书通常挂在 加速域名 上。用户浏览器校验的是业务域名,所以证书 SAN 必须覆盖 static.example.com,而不是只覆盖厂商 CNAME 域名。
四、串起来:一次真实访问长什么样
以访问 https://static.example.com/app.a1b2c3.js 为例(拆成 DNS 阶段 与 HTTP 阶段):
【DNS】
1. 浏览器查询 static.example.com
2. 得到 CNAME → 厂商加速域名
3. 再解析加速域名,得到就近边缘节点 IP(GSLB / Anycast)
【HTTP】
4. 浏览器直接与该边缘 IP 建连(TLS 仍校验业务域名)
5. POP 用 Cache Key 查找 app.a1b2c3.js
6. HIT → 直接返回;MISS → 边缘 HTTP 回源 → 按 Cache-Control 写入 → 返回
7. 浏览器按自身缓存策略再存一份;对外仍表现为「访问了 static.example.com」
排障也可按同一顺序想:
| 步骤 | 先看什么 | 常见问题 |
|---|---|---|
| ① 域名 / DNS | CNAME 是否指到正确加速域名;是否误配成 A | 指错环境、忘改 DNS、apex 乱挂 CNAME |
| ② 调度 | 解析到的 IP 是否为本地区/本运营商节点 | DNS 污染、公司出口导致「调度漂」 |
| ③ 边缘缓存 | 响应头是否 HIT,TTL 是否符合预期 | 查询参数未忽略导致拆键、Cookie 导致不缓存 |
| ④ 回源 | 源站状态码、Host、回源 IP 白名单 | 源站 4xx/5xx、证书、超时 |
| ⑤ 浏览器 | 本地强缓存是否还拿着旧文件 | 未改 hash 又未刷新 |
五、实战操作
不申请整套生产域名,也可以用「观察」建立直觉。
5.1 看一个站点是不是走了 CDN
# 看是否 CNAME 到厂商
dig static.example.com +short
# 或
nslookup static.example.com
若看到 *.cdn.* / *.kunlun* / *.cloudfront.net / *.cdn.cloudflare.net 一类名字,业务上通常就是「域名已经交给 CDN 调度」。最终 A 记录往往是边缘入口,而不是你那台应用机的公网 IP。
5.2 看一次响应有没有命中边缘
curl -sI "https://static.example.com/app.a1b2c3.js"
重点看:
| 响应头 | 可能说明 |
|---|---|
Age | 对象已在共享缓存里待了多少秒 |
X-Cache / X-Cache-Lookup(厂商各异) | HIT / MISS / EXPIRED |
Cache-Control / ETag | 源站(或 CDN 改写后)的缓存策略 |
Via / Server / x-swift-* 等 | 经过了反向代理 / CDN |
第一次 curl 常是 MISS,紧接着再 curl 一次更可能 HIT——这就是「前置仓补货」的现场版。
5.3 用响应头区分「浏览器缓存」和「CDN 缓存」
- 浏览器磁盘/内存缓存:你不再发请求,或只发协商请求(
304)。 - CDN 边缘缓存:请求已经到达 POP,但 POP 不必回源。
DevTools 里「from disk cache」不等于 CDN HIT;要用 curl -I 或关掉本地缓存再看响应头。
六、生产建议与扩展方向
| 建议 | 原因 |
|---|---|
| 静态资源独立域名 + 文件名 hash + 长 TTL | 更新靠改名,少依赖刷新 |
| 动态接口默认不缓存,必要时单独规则 | 避免把带登录态的页面缓存给别人 |
| 源站只放行 CDN 回源 IP | 防止绕过边缘直打、也便于防攻击 |
| 监控命中率、回源带宽、4xx/5xx、回源耗时 | 命中率掉了往往是拆键、Cookie、TTL 配错 |
| 大促前对超热 URL 预热 | 把开场回源峰值从源站挪走 |
| 文档写清「业务域名 / 加速域名 / 源站」三列 | 减少沟通时改错 DNS 或改错 Host |
可继续延伸阅读的方向:
- Cache Key 规范化(忽略无意义 query、是否带
/、大小写); - 多级缓存(边缘 → 区域中心 → 源站);
- HTTP/2 推送已过时,HTTP/3 / QUIC 在弱网下的收益;
- 回源签名 URL、防盗链、Referer / UA 策略;
- CDN 与源站 VIP、对象存储、直播中心如何分工。
七、一句话收束
CDN 是把内容缓存在离用户更近的边缘(CDN)节点上的分发网络;它的用处是就近加速、降低源站带宽,并在未命中时按规则回源。
DNS 是整套解析系统,CNAME 只是其中的别名记录——用来在解析阶段把业务域名指到 CDN,并不转发 HTTP;用户连上的是边缘节点 IP,回源才是边缘与源站之间的 HTTP。日常可说「CDN 节点就是边缘节点」,严格说边缘更广、CDN 缓存节点是其中一类。静态、点播、下载最适合长缓存;动态接口要单独评估。
整理完毕,完结撒花~🌻
火山引擎视频云技术社区,是面向 AI 音视频开发者的技术交流平台。这里汇聚源自抖音、豆包等亿级 DAU 产品的 RTC、直播、点播、AI 媒体处理、音视频互动技术,提供接入指南、最佳实践、性能调优、场景案例、Demo 代码、开源项目、白皮书和 API 文档。社区汇聚官方工程师与一线开发者,为 AI 视频通话、数字人、AI 视频处理等应用的开发与落地提供技术支持。
更多推荐
所有评论(0)