- CDN 就是将静态资源分发到多个不同的地方以实现就近访问,进而加快静态资源的访问速度,减轻服务器以及带宽的负担。
- 基于成本、稳定性和易用性考虑,建议直接选择专业的云厂商或者 CDN 厂商的 CDN 服务。
- GSLB (Global Server Load Balance,全局负载均衡)是 CDN 的大脑,负责多个 CDN 节点之间相互协作,最常用的是基于 DNS 的 GSLB。CDN 会通过 GSLB 找到最合适的 CDN 节点。
- 为了防止静态资源被盗用,我们可以利用 Referer 防盗链 + 时间戳防盗链。
- CDN 是否需要更新,可以利用 HTTP 缓存 + 304 状态来判断。
概念
CDN(Content Delivery Network,内容分送网络)我们可以将内容分发网络拆开来看:
- 内容:指的是静态资源比如图片、视频、文档、JS、CSS、HTML。
- 分发网络:指的是将这些静态资源分发到位于多个不同的地理位置机房中的服务器上,这样,就可以实现静态资源的就近访问比如北京的用户直接访问北京机房的数据。
所以,简单来说,CDN 就是将静态资源分发到多个不同的地方以实现就近访问,进而加快静态资源的访问速度,减轻服务器以及带宽的负担。
CDN 特性
- 内容分发:CDN 会在全球部署多个边缘服务器(Edge Server),这些服务器位于不同的地理区域。
- 缓存机制:当用户请求内容时,CDN 会根据用户的地理位置将请求重定向到最近的边缘服务器。边缘服务器会缓存来自原始服务器的内容。
- 负载均衡:CDN 可以帮助分散流量,防止单一服务器过载,提高了系统的可用性和可靠性。
- 安全性:CDN 还可以提供 DDoS 防护和其他安全措施,保护源站服务器免受攻击。
- 资源压缩:帮忙压缩静态资源,把 jpg, png 之类的图片转成 webp 和 avif ,浏览器不支持的话再降级到原来的图片。
CDN vs 全站加速
我们经常拿全站加速和内容分发网络做对比,不要把两者搞混了!全站加速(不同云服务商叫法不同,腾讯云叫 ECDN、阿里云叫 DCDN)既可以加速静态资源又可以加速动态资源,内容分发网络(CDN)主要针对的是 静态资源。
为什么不直接将服务部署在多个不同的地方
- 成本太高,需要部署多份相同的服务。
- 静态资源通常占用空间比较大且经常会被访问到,如果直接使用服务器或者缓存来处理静态资源请求的话,对系统资源消耗非常大,可能会影响到系统其他服务的正常运行。
- 自建机房,成本比较大,一般公司成本划不来。
同一个服务在在多个不同的地方部署多份(比如同城灾备、异地灾备、同城多活、异地多活)是为了实现系统的高可用而不是就近访问。
CDN 工作原理
静态资源是如何被缓存到 CDN 节点中的?
你可以通过 预热 的方式将源站的资源同步到 CDN 的节点中。这样的话,用户首次请求资源可以直接从 CDN 节点中取,无需回源。这样可以降低源站压力,提升用户体验。
如果不预热的话,你访问的资源可能不在 CDN 节点中,这个时候 CDN 节点将请求源站获取资源,这个过程是大家经常说的 回源。
- 回源:当 CDN 节点上没有用户请求的资源或该资源的缓存已经过期时,CDN 节点需要从原始服务器获取最新的资源内容,这个过程就是回源。当用户请求发生回源的话,会导致该请求的响应速度比未使用 CDN 还慢,因为相比于未使用 CDN 还多了一层 CDN 的调用流程。
- 预热:预热是指在 CDN 上提前将内容缓存到 CDN 节点上。这样当用户在请求这些资源时,能够快速地从最近的 CDN 节点获取到而不需要回源,进而减少了对源站的访问压力,提高了访问速度。
如果资源有更新的话,你也可以对其 刷新 ,删除 CDN 节点上缓存的旧资源,并强制 CDN 节点回源站获取最新资源。
几乎所有云厂商提供的 CDN 服务都具备缓存的刷新和预热功能(下图是阿里云 CDN 服务提供的相应功能):
命中率 和 回源率 是衡量 CDN 服务质量两个重要指标。命中率越高越好,回源率越低越好。
如何让请求到达 CDN?
图片肯定不是直接通过 IP 访问的,而是通过域名访问的,这样可以避免 IP 变更后,图片访问不到。
DNS 的域名解析结果一般有两种,一种叫做“A 记录”,返回的是域名对应的 IP 地址;另一种是“CNAME 记录”,返回的是另一个域名,也就是说当前域名的解析要跳转到另一个域名的解析上。
实际上 www.baidu.com 域名的解析结果就是一个 CNAME 记录,域名的解析被跳转到 www.a.shifen.com 上了。
比如你的公司的一级域名叫做 example.com,那么你可以把你的图片服务的域名定义为“img.example.com”,然后将这个域名的解析结果的 CNAME 配置到 CDN 提供的域名上。
比如 uclound 可能会提供一个域名是“80f21f91.cdn.ucloud.com.cn”这个域名。这样你的电商系统使用的图片地址可以是“http://img.example.com/1.jpg”。用户在请求这个地址时,DNS 服务器会将域名解析到 80f21f91.cdn.ucloud.com.cn 域名上,然后再将这个域名解析为 CDN 的节点 IP,这样就可以得到 CDN 上面的资源数据了。
具体链路如下所示:

如何找到最合适的 CDN 节点?
GSLB (Global Server Load Balance,全局负载均衡)是 CDN 的大脑,负责多个 CDN 节点之间相互协作,最常用的是基于 DNS 的 GSLB。
CDN 会通过 GSLB 找到最合适的 CDN 节点,更具体点来说是下面这样的:
- 浏览器向 DNS 服务器发送域名请求;
- DNS 服务器向根据 CNAME( Canonical Name ) 别名记录向 GSLB 发送请求;
- GSLB 返回性能最好(通常距离请求地址最近)的 CDN 节点(边缘服务器,真正缓存内容的地方)的地址给浏览器;
- 浏览器直接访问指定的 CDN 节点。

为了方便理解,上图其实做了一点简化。GSLB 内部可以看作是 CDN 专用 DNS 服务器和负载均衡系统组合。CDN 专用 DNS 服务器会返回负载均衡系统 IP 地址给浏览器,浏览器使用 IP 地址请求负载均衡系统进而找到对应的 CDN 节点。
GSLB 是如何选择出最合适的 CDN 节点呢? GSLB 会根据请求的 IP 地址、CDN 节点状态(比如负载情况、性能、响应时间、带宽)等指标来综合判断具体返回哪一个 CDN 节点的地址。
如何防止资源被盗刷?
如果我们的资源被其他用户或者网站非法盗刷的话,将会是一笔不小的开支。
解决这个问题最常用最简单的办法设置 Referer 防盗链,具体来说就是根据 HTTP 请求的头信息里面的 Referer 字段对请求进行限制。我们可以通过 Referer 字段获取到当前请求页面的来源页面的网站地址,这样我们就能确定请求是否来自合法的网站。
CDN 服务提供商几乎都提供了这种比较基础的防盗链机制。
不过,如果站点的防盗链配置允许 Referer 为空的话,通过隐藏 Referer,可以直接绕开防盗链。
通常情况下,我们会配合其他机制来确保静态资源被盗用,一种常用的机制是 时间戳防盗链 。相比之下,时间戳防盗链 的安全性更强一些。时间戳防盗链加密的 URL 具有时效性,过期之后就无法再被允许访问。
时间戳防盗链的 URL 通常会有两个参数一个是签名字符串,一个是过期时间。签名字符串一般是通过对用户设定的加密字符串、请求路径、过期时间通过 MD5 哈希算法取哈希的方式获得。
时间戳防盗链 URL 示例:
http://cdn.wangsu.com/4/123.mp3? wsSecret=79aead3bd7b5db4adeffb93a010298b5&wsTime=1601026312
wsSecret:签名字符串。wsTime: 过期时间。
时间戳防盗链的实现也比较简单,并且可靠性较高,推荐使用。并且,绝大部分 CDN 服务提供商都提供了开箱即用的时间戳防盗链机制。
除了 Referer 防盗链和时间戳防盗链之外,你还可以 IP 黑白名单配置、IP 访问限频配置等机制来防盗刷。
如何识别到我们本地的静态数据有更新的呢
集中方式其中有 http304 方式检测,expire 超时检测,etag 检测等~
CDN 缺陷
- CDN 成本可能因流量而异,可能在权衡之后你将不会使用 CDN。
- 如果在 TTL 过期之前更新内容,CDN 缓存内容可能会过时。
- CDN 需要更改静态内容的 URL 地址以指向 CDN。
Reference
- JavaGuide 中 CDN 专题
- “高并发系统设计 40 问” 中 16 | CDN:静态资源如何加速?