CDN基本原理
CDN(Content Delivery Network)即内容分发网络,是一种网络加速技术。其目的是使用户可就近取得所需内容,解决 Internet网络拥挤的状况,提高用户访问网站的响应速度。CDN依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。
为什么要用CDN
假设一个位于杭州的用户,要访问源站在北京的网络服务,那么每一次请求都需要经历从杭州到北京再到杭州的完整链路。如果用户访问的是图片、视频类的网站,那么在较高并发的情况下,大量的静态资源I/O会给服务器造成不小的压力,且客户端加载速度缓慢也容易造成用户流失。
如果能将服务器源站的静态资源,如图片、视频、css、js等文件缓存到位于上海(或者更近)的cdn服务器中,那么用户就不必从每次都从北京获取数据,而是访问距离更近的cdn节点,既可加快访问速度,又减少了源站服务器的压力。
如何实现原本要访问源站的请求转而访问到cdn节点上呢?
从DNS说起
我们知道,要访问网站 www.baidu.com 的内容,客户端系统需要先获取域名 www.baidu.com 对应的IP地址,然后再往该IP地址发送HTTP(S) 请求。根据域名获取IP地址的过程即DNS查询,整个过程大致如下:
- 查询浏览器缓存或本地host文件。
- 客户端向运营商DNS服务器(local dns)发起查询请求。
- local dns查询本地缓存,存在则返回对应IP,否则继续查询根域名服务器。
- 根域名服务器根据一级域名类型(如 .com)返回对应一级域名服务器地址。
- 一级域名服务器查询本地缓存,返回对应IP或二级域名(如 baidu.com)解析的服务器地址。
- 二级域名服务器查询本地缓存,返回对应IP或三级域名(如 www.baidu.com)解析的服务器地址。
- 如此重复,直到完成域名解析,local dns 将最终获取到的IP返回客户端。
CNAME
了解了DNS查询的过程,可以发现,如果我们将域名 www.baidu.com 的IP解析到cdn节点而非真正的源站,就实现了请求转发的过程。这一过程正是通过CNAME实现。
对于第三方的cdn服务商(如阿里云),并不能很好的控制运营商DNS服务器的返回结果,因此,一般会选择在一级域名服务器或二级域名服务器查询时,返回一条CNAME记录。CNAME是一个新的域名,如www.baidu.com的CNAME是 www.a.shifen.com,阿里云CDN上分配的CNAME格式一般为 源站域名.w.alikunlun.com。
客户端在拿到CNAME后,会发起一个新的dns查询请求。以www.test.com.w.alikunlun.com为例,其二级域名为 alikunlun.com,因此,local dns在发起二级域名查询时,请求就落到了阿里云自己的dns服务器上,其内部就可以执行自己的调度策略,从而返回最优的cdn节点IP给到客户端。
根据local dns的缓存策略,在之后的请求中,无论是源站域名还是CNAME的dns解析,都会被缓存下来,从而简化dns查询流程。
dig命令可用来显示整个dns查询过程,可以看到,www.baidu.com 的CNAME是www.a.shifen.com,其可用cdn ip有两个,分别为 180.101.49.11 和 180.101.49.12。
分层架构
在cdn基础架构中,往往采用两层架构。如下图所示。
L1(下层):距离用户越近越好,通常用于缓存那些可缓存的静态数据,称之为 lastmile(最后一公里)。
L2(上层):距离源站越近越好,称之为 firstmile(第一公里),当L1无法命中缓存,或内容不可缓存时,请求会通过回源到L2,若L2仍然没有命中缓存或内容不可缓存,则会继续回源到源站。同时L2还可以用来做流量、请求数的量级收敛,减少回源量(如果可缓存),降低源站压力。L1和L2之间的部分,是CDN的“内部网络”,称之为 middlemile(中间一公里)。
调度策略
cdn调度的主要任务之一是返回一个距离用户尽可能近的cdn节点。
LDNS调度是一种基于local dns的调度策略。从dns的查询过程来看,cdn服务商的dns服务器接收到的请求来自于local dns 而非真实用户,所以,LDNS调度选择的cdn节点距离远近也是相对于local dns而言的。这就存在一种情况,如果用户客户端上设置的dns服务器地址距离自己较远(如一个中国的用户将dns设置成了8.8.8.8),那么最终调度到的cdn节点将是位于美国的cdn服务器,这就失去了加速的效果。
HTTP 302调度是另一种调度策略,它是为了解决LDNS调度以上问题而提出的一种策略。因为无论local dns返回了哪个cdn节点,客户端都会往该节点发送请求,这个时候,cdn节点就能获取到客户端真正的ip地址。cdn内部只需要做一个判断,如果有更合适的cdn节点,就将请求302到新的cdn节点地址中去。这就实现了重新调度。
除了 DNS 调度、HTTP 302 调度,还有一种使用 HTTP 进行的 DNS 调度策略。随着技术的逐渐发展,也出现了新的技术和设备,例如劫持。劫持后,网民所访问的目标有可能不再是真实服务器,即使是真实服务器,内容也有可能是虚假的、被替换过的,这对业务安全来说是十分危险的,这种劫持现象多出现在移动互联网(手机上网)。为了规避这种问题,出现了一种 HTTP DNS 的调度方式,原理是通过 HTTP 报文传输 DNS 请求和应答信息。但这种方式没有任何 RFC 的支持,所以没有任何现成的操作系统直接支持,必须有自己的 HTTP DNS 客户端,来与 HTTP DNS 服务端进行通信,需要双端支持。这种做法在 APP 中使用较多。