docs/high-performance/cdn.md
CDN 全称是 Content Delivery Network/Content Distribution Network,翻译过的意思是 内容分发网络 。
我们可以将内容分发网络拆开来看:
简单来说,CDN 就是将静态资源分发到多个不同的地方以实现就近访问,进而加快静态资源的访问速度,减轻源站服务器以及带宽的负担。
类似于京东建立的庞大仓储运输体系,京东物流在全国拥有非常多的仓库,仓储网络几乎覆盖全国所有区县。这样的话,用户下单的第一时间,商品就从距离用户最近的仓库直接发往对应的配送站,再由京东小哥送到你家。
你可以将 CDN 看作是服务上一层的特殊缓存服务,分布在全国各地,主要用来处理静态资源的请求。
我们经常拿全站加速和内容分发网络做对比,不要把两者搞混了!全站加速(不同云服务商叫法不同,腾讯云叫 ECDN、阿里云叫 DCDN)既可以加速静态资源又可以加速动态资源,而内容分发网络(CDN) 主要针对的是 静态资源 。
绝大部分公司都会在项目开发中使用 CDN 服务,但很少会有自建 CDN 服务的公司。基于成本、稳定性和易用性考虑,建议直接选择专业的云厂商(比如阿里云、腾讯云、华为云、青云)或者 CDN 厂商(比如网宿、蓝汛)提供的开箱即用的 CDN 服务。
很多朋友可能要问了:既然是就近访问,为什么不直接将服务部署在多个不同的地方呢?
这涉及到静态资源与动态请求的架构分离问题:
注意:同一个服务在多个不同地方部署多份(比如同城灾备、异地灾备、同城多活、异地多活)是为了实现系统的高可用,而不是就近访问。
理解 CDN 的工作原理,需要搞懂以下三个核心问题:
CDN 缓存静态资源的方式主要有两种:预热和回源。
预热(Prefetch):主动将源站的资源推送到 CDN 节点中。这样用户首次请求资源时可以直接从 CDN 节点获取,无需回源,适用于大促活动、热点内容发布等场景。
回源(Origin Pull):当 CDN 节点上没有用户请求的资源或该资源的缓存已过期时,CDN 节点需要从源站获取最新的资源内容。
注意:当用户请求触发回源时,该请求的响应速度会比未使用 CDN 还慢,因为相比于直接访问源站,多了一层 CDN 节点的调用流程。因此,提高缓存命中率是 CDN 优化的关键目标。
CDN 缓存的完整生命周期如下图所示:
如果资源有更新,可以对其进行刷新操作,删除 CDN 节点上缓存的旧资源,并强制 CDN 节点在下次请求时回源获取最新资源。
几乎所有云厂商提供的 CDN 服务都具备缓存的刷新和预热功能(下图是阿里云 CDN 服务提供的相应功能):
命中率和回源率是衡量 CDN 服务质量的两个核心指标:
GSLB(Global Server Load Balance,全局负载均衡) 是 CDN 的大脑,负责多个 CDN 节点之间的协调调度,最常用的实现方式是基于 DNS 的 GSLB。
CDN 请求的完整调度流程如下图所示:
sequenceDiagram
participant User as 用户浏览器
participant LocalDNS as 本地 DNS
participant AuthDNS as 权威 DNS
participant GSLB as CDN 全局负载均衡
participant Edge as CDN 边缘节点
participant Origin as 源站服务器
User->>LocalDNS: 1. 请求解析 cdn.example.com
LocalDNS->>AuthDNS: 2. 查询域名
AuthDNS-->>LocalDNS: 3. 返回 CNAME 记录指向 CDN
LocalDNS->>GSLB: 4. 请求 CDN 域名解析
Note over GSLB: 根据用户 IP、节点负载、
网络状况等选择最优节点
GSLB-->>LocalDNS: 5. 返回最优 CDN 节点 IP
LocalDNS-->>User: 6. 返回 CDN 节点 IP
User->>Edge: 7. 请求静态资源
alt 缓存命中
Edge-->>User: 8a. 直接返回缓存资源
else 缓存未命中
Edge->>Origin: 8b. 回源请求
Origin-->>Edge: 9. 返回资源
Note over Edge: 缓存资源
Edge-->>User: 10. 返回资源
end
详细流程说明:
补充说明:上图做了一定简化。实际上,GSLB 内部可以看作是 CDN 专用 DNS 服务器和负载均衡系统的组合。CDN 专用 DNS 服务器会返回负载均衡系统的 IP 地址,浏览器通过该 IP 请求负载均衡系统,进而找到对应的 CDN 节点。
如果静态资源被其他用户或网站非法盗刷,将会产生大量额外的带宽费用。常见的防盗链机制有以下几种:
| 防盗链机制 | 原理 | 安全强度 | 实现成本 | 绕过难度 |
|---|---|---|---|---|
| Referer 防盗链 | 根据 HTTP 请求头中的 Referer 字段判断请求来源 | 低 | 低 | 低(可伪造或置空 Referer) |
| 时间戳防盗链 | URL 中携带签名和过期时间,过期后 URL 失效 | 中 | 中 | 中(需要获取签名算法) |
| IP 黑白名单 | 限制或允许特定 IP 地址访问 | 中 | 低 | 中(可通过代理绕过) |
| Token 鉴权 | 业务服务器生成 Token,CDN 节点校验 | 高 | 高 | 高 |
通过检查 HTTP 请求头中的 Referer 字段来判断请求来源是否合法。可以配置允许访问的域名白名单,非白名单来源的请求将被拒绝。
CDN 服务提供商几乎都支持这种基础的防盗链机制:
注意:如果防盗链配置允许 Referer 为空,攻击者可以通过隐藏 Referer 的方式绕过防盗链检查。因此,Referer 防盗链通常需要配合其他机制一起使用。
时间戳防盗链的安全性更强,其核心原理是:URL 中携带签名字符串和过期时间,CDN 节点在处理请求时会校验签名并检查是否过期,过期的 URL 将被拒绝访问。
签名字符串通常通过对加密密钥 + 请求路径 + 过期时间进行 MD5 哈希计算得到。
时间戳防盗链 URL 示例:
http://cdn.example.com/video/123.mp4?wsSecret=79aead3bd7b5db4adeffb93a010298b5&wsTime=1601026312
wsSecret:签名字符串,由服务端根据密钥和请求信息计算生成。wsTime:过期时间戳(Unix 时间戳格式)。绝大部分 CDN 服务提供商都支持开箱即用的时间戳防盗链机制:
推荐实践:生产环境建议采用 Referer 防盗链 + 时间戳防盗链的组合方案,兼顾安全性与实现成本。对于安全性要求极高的场景(如付费内容),可进一步引入 Token 鉴权机制。
传统的 CDN 主要针对静态资源(如图片、CSS、JS)进行缓存加速,而对于动态资源(如 API 接口、实时查询、支付请求、.jsp/.asp/.php 等动态页面),内容实时变化无法缓存,传统 CDN 往往直接回源,加速效果有限。
动态加速(Dynamic Content Acceleration) 正是为了解决这一问题而设计。它不缓存内容,而是通过智能路由、协议优化等技术,提升动态请求的传输速度和稳定性。
动态加速主要通过以下三种技术手段实现:
智能路由选路(最优链路探测):动态请求从用户端发出后,先到达离用户最近的 CDN 边缘节点。CDN 内部通过实时网络监测技术,探测全网链路质量(包括延迟、丢包率、带宽负载),避开公网中的拥堵或质量较差的节点,选择一条最优的传输路径到达源站。
传输协议优化:
动静态混合加速:现代 CDN(如阿里云 DCDN、腾讯云 ECDN)能够自动识别用户请求的资源类型:
一句话总结:动态加速 = 智能探测 + 动态选路 + 协议优化,让动态请求跑得又快又稳。
HTTPS 虽然安全,但 TLS 握手和加解密过程会增加延迟。CDN 通过多种技术手段对 HTTPS 进行加速优化,在保障安全的同时提升访问速度。
| 优化技术 | 原理说明 | 效果 |
|---|---|---|
| 会话复用 | 用户首次建立 HTTPS 连接后,节点缓存会话信息;再次访问时复用会话参数,减少完整 TLS 握手 | 减少握手延迟 |
| OCSP Stapling | 由 CDN 节点定期缓存证书状态,在 TLS 握手时一并发给浏览器,避免浏览器单独查询 CA 机构 | 提升握手效率 |
| False Start | 在 TLS 握手尚未完全完成时就开始传输加密数据 | 减少一个 RTT 开销 |
| HTTP/2 | 支持多路复用、头部压缩 | 减少连接数和传输延迟 |
| QUIC | 基于 UDP 的传输协议,0-RTT 建立连接 | 减少连接建立时间,改善弱网体验 |
CDN 证书托管的优势:
CDN 服务商(如腾讯云、阿里云)通常提供免费 SSL 证书和自动续期服务,具有以下优势:
HTTPS 加速的配置建议: