CDN
即内容分发网络Content Delivery Network
,CDN
的基本原理是广泛采用各种缓存服务器,将这些缓存服务器分布到用户访问相对集中的地区或网络中,在用户访问网站时,利用全局负载技术将用户的访问指向距离最近的工作正常的缓存服务器上,由缓存服务器直接响应用户请求,CDN
的基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定,通过在网络各处放置节点服务器所构成的在现有的互联网基础之上的一层虚拟网络,CDN
系统能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上,其目的是使用户可就近取得所需内容,解决Internet
网络拥挤的状况,提高用户访问网站的响应速度。
CDN
系统由分发服务系统、负载均衡系统和运营管理系统组成:分发服务系统主要负责资源的响应、缓存和同步。负载均衡系统主要负责均衡单点多个内容缓存设备的负载,并对内容进行缓存负载平衡及访问控制,以及对用户请求进行调度以及路由。运营管理系统则负责运营需求管理和网络系统管理。CDN
系统主要分为边缘层和中心层,边缘层分布在CDN
网络的边缘位置,给用户提供就近访问服务,中心层则负责完成资源同步和运营管理等功能。中心层保存了加速域名的相关配置信息比如源站域名,也缓存了加速域名下的各种资源,在边缘层节点未命中缓存时,需要向中心层节点发起请求,而中心层节点未能命中缓存时,需要查找对应的源站域名,并向该源站域名发起请求,然后再逐层返回并缓存用户请求的资源。POP
节点存储能力。IDC
能力和IDC
策略性分布。DNS
的负载均衡以CNAME
实现最优节点服务。DNS
服务器缓存。DNS
地址缓存、客户请求内容缓存、动态内容缓存。HTTPS
带证书加速、下载加速等等。使用CDN
服务提供商的CDN
服务时,需要做一些配置:
解析一个子域名,可以先随意解析到某个地址,例如是cdn.example.com
。
到服务提供商添加该域名,并设置源站域名,例如是www.example.com
。
此时服务商一般会分配一个CNAME
地址,例如是cdn.example.com.service.com
。
将第一步的域名添加CNAME
记录为分配的CNAME
地址。
或者服务商在第一步即提供了CNAME
地址,那么直接解析即可。
简单的CDN
的访问流程,这是一种pull
的方式拉取缓存:
DNS
解析该域名。CNAME
地址,之后解析CNAME
地址。CNAME
域名对应的IP
地址,指向CDN
边缘层节点。CDN
边缘层节点未命中资源缓存,则向中心层节点请求。path
是不会变化的。在计算机中有两大难题,一是缓存何时失效,二是如何命名,而CDN
中缓存何时失效是一个比较麻烦的问题,假如源站的资源文件发生变化,而用户此时取得的资源是从缓存节点中取得的,此时就会造成资源文件不一致的现象,解决这个问题可以通过主动push
刷新所有CDN
缓存的方式来实现,但是这种方式成本较高,比较简单的解决方案就是在固定时间段过后便使缓存失效,除了节点的缓存需要控制,还需要控制用户本地缓存,在HTTP
协议中提供了如下缓存控制的方式:
强缓存是通过Expires
与Cache-Control
来控制缓存在本地的有效期。
Expires
是HTTP 1.0
提出的一个表示资源过期时间的Header
,它描述的是一个绝对时间,由服务器返回。Expires
受限于本地时间,如果修改了本地时间,可能会造成缓存失效.对于资源的请求,如果在Expires
之内,则浏览器会直接读取缓存,不再请求服务器。
Cache-Control
出现于HTTP 1.1
,优先级高于Expires
,表示的是相对时间,请求头和响应头都支持这个属性,通过它提供的不同的值来定义缓存策略。
Cache-Control: no-store
: 缓存中不得存储任何关于客户端请求和服务端响应的内容,每次由客户端发起的请求都会下载完整的响应内容。
Cache-Control: no-cache
: 缓存中会存储服务端响应的内容,只是在与服务端进行新鲜度再验证之前,该缓存不能够提供给浏览器使用。简单来说,就是浏览器会将服务端响应的资源进行缓存,但是在每次请求时,缓存都要向服务端评估缓存响应的有效性,协商缓存是否可用,根据响应是304
还是200
判断是使用本地缓存资源还是使用服务器响应的资源。
Cache-Control: public || private
: public
表示该响应可以被任何中间人比如中间代理、CDN
等缓存。默认响应为private
,private
表示该响应是专用的,中间人不能缓存此响应,该响应只能应用于浏览器私有缓存中。
Cache-Control: max-age=31536000
: 响应为最大的过期时间,其指令是max-age=<seconds>
,表示资源能够被缓存即保持新鲜的最大时间,max-age
是距离请求发起的时间的秒数。
Cache-Control: must-revalidate
: 当使用了must-revalidate
指令,那就意味着缓存在考虑使用一个陈旧的资源时,必须先验证它的状态,已过期的缓存将不被使用。在正常情况下是没有必要使用这个指令的,因为在强缓存过期的情况下会进行协商缓存,但是HTTP
规范是允许客户端在某些特殊情况下直接使用过期缓存的,比如校验请求发送失败的时候,还比如有配置一些特殊指令stale-while-revalidate
、stale-if-error
等的时候,must-revalidate
指令就是让缓存在过期后的任何情况下都必须重新验证。
当浏览器对某个资源的请求没有命中强缓存,就会发一个请求到服务器,验证协商缓存是否命中,如果协商缓存命中,请求响应返回的HTTP
状态为304 (Not Modified)
,该请求不携带实体数据,若未命中,则返回200
并携带资源实体数据。协商缓存是利用的是Last-Modified,If-Modified-Since
和ETag、If-None-Match
这两对Header
来管理的。
Last-Modified,If-Modified-Since
是HTTP 1.0
引入的,Last-Modified
表示本地文件最后修改日期,浏览器会在请求头加上If-Modified-Since
即上次响应的Last-Modified
的值,询问服务器在该日期后资源是否有更新,有更新的话就会将新的资源发送回来,但是如果在本地打开缓存文件,就会造成Last-Modified
被修改,所以在HTTP 1.1
出现了ETag
。
Etag
就像一个指纹,资源变化都会导致ETag
变化,跟最后修改时间没有关系,ETag
可以保证每一个资源是唯一的,If-None-Match
的请求头字段会将上次返回的Etag
发送给服务器,询问该资源的Etag
是否有更新,有变动就会发送新的资源回来。ETag
的优先级比Last-Modified
更高,具体使用ETag
主要出于下面几种情况考虑:
一些文件也许会周期性的更改,但是他的内容并不改变,比如仅仅改变的修改时间,这个时候我们并不希望客户端认为这个文件被修改了,而重新GET
。
某些文件修改非常频繁,比如在秒以下的时间内进行修改,例如1s
内修改了N
次,If-Modified-Since
能检查到的粒度是秒级的,这种修改无法判断。
某些服务器不能精确的得到文件的最后修改时间。