# CDN

## 一、简介

CDN中文就是内容分发网络（Content Delivery Network）。其目的是在现有的网络中增加一层网络架构，将网站的内容发布到最接近用户的网络“边缘”，使用户可以就近取得所需的内容，提高用户访问网站的响应速度。有别于镜像，它比镜像更加智能，可以理解为：CDN=镜像（Mirror）+缓存（Cache）+整体负载均衡（GSLB）。

目前CDN都以缓存网站中的静态数据为主，如CSS、JS、图片和静态页面等数据。用户从主站服务器中请求到动态内容后，再从CDN上下载静态数据，从而加速网页数据内容的下载速度。

## 二、CDN架构

通常来说CDN要达到以下几个目标：

* 可拓展性：性能可扩展性，应对新增的大量数据、用户和事务的拓展能力。成本可扩展性，用低廉的运营成本提供动态的服务能力和高质量的内容分发；
* 安全性：强调提供物理设备、网络、软件、数据和服务过程的安全性，减少因为DDos攻击或者其他恶意行为；
* 可靠性、响应和执行：服务可用性指能够处理可能的故障和用户体验下降的问题，通过负载均衡及时提供网络的容错机制。

访问拥有CDN的网站的静态资源流程：

一个用户访问某个静态文件，如CSS文件，首先向Local DNS服务器发起请求，一般经过迭代解析后回到这个域名的注册服务器去解析，这个域名最终会被指向CDN全局中的DNS负载均衡器，再由这个GTM来最终分配是哪个地方的访问用户，返回给离这个用户最近的CDN节点。用户拿到DNS解析结果就直接去这个CDN节点访问这个静态文件了。如果这个文件不存在，会回到源站去获取这个文件，并且CDN会本节点上缓存一份，方便下次用户来访问。

## 三、负载均衡

负载均衡就是将大量的请求通过一定的策略分摊到不同的服务节点。他可以提高服务器的影响速度及利用效率，避免软件或者硬件模块出现单点失效，解决网络拥塞问题，实现地理位置无关性，为用户提供较一致的访问质量。

通常有三种负载均衡架构：链路负载均衡、集群负载均衡和操作系统负载均衡。

* 链路负载均衡：就是前面提到的CDN架构通过DNS解析成不同的IP，然后用保护根据这个IP来访问不同的目标服务器，链路负载均衡是由DNS的解析来完成的。
* 集群负载均衡：一般分为硬件负载均衡和软件负载均衡。硬件负载均衡一般使用一台专门的硬件设备来转发请求，关键就是这台昂贵的设备，如F5，通常为了安全 需要一主一备，它的优点就是性能非常好，缺点就是非常贵，一般公司用不起，还有就是不支持动态扩容。软件负载均衡比较普遍，特点就是成本低，直接使用廉价的PC就可以搭建，缺点就是一般一次访问请求要经过多次代理服务器，会增加网络延时。
* 操作系统负载均衡：利用操作系统级别的软件中断或者硬件中断来达到负载均衡，如可以设置多队列网卡等来实现。

## 四、CDN动态加速

CDN动态加速技术是当前比较流行的一种优化技术，它的技术原理是在CDN的DNS解析中通过动态的链路探测来寻找回源最好的一条路径，然后通过DNS的调度将所有请求调度到选定的这条路径上回源，从而加快用户访问的效率。

由于CDN节点是遍布全国的，所以用户接入一个CDN节点后，可以选择一条从离用户最近的CDN节点到源站链路最好的路径让用户走。判断最好的路径不一定把耗时当做唯一标准，有时也要考虑网络成本，还有其他网络链路的安全等因素也要综合考虑。

## 疑问

1. 如果源站有静态文件更新，如何同步CDN节点？有什么策略？
2. 主动刷新缓存：源站更新后主动刷新CDN缓存；
3. 静态资源重命名：编译静态文件的时候文件名带上时间戳或者序列号，一旦更新，由于文件名不一样，那么CDN就会去源站拉取最新文件；
4. 缓存时间：源站控制CDN的缓存时间，过期资源强制从源站重新拉取；
5. 更改URL：设置CDN在缓存的时候，不忽略参数， 即，缓存的key为完整的URI，如果想要访问到最新的资源，可以通过在请求URI后面带上不同的参数，然后请求到CDN节点的时候会直接回源，拉取到最新的资源。

> 参考：
>
> 《深入分析Java Web技术内幕》
>
> CDN 如何保证数据节点的更新和同步？：[https://www.zhihu.com/question/39147728](https://www.zhihu.com/question/39147728)
