CDN缓存策略
CDN(Content Delivery network,内容分发网络),通过GSLB技术使得用户能访问到最近物理机房的文件,以节省网络时间,也就是说一份文件可能会在全国乃至全球的多个服务器存在,这就涉及到一个文件分发的问题,目前通常的CDN都是采取回源策略来同步文件,即每个cdn域名关联了一些源服务器,发布文件只要发布到源服务器即可,cdn会根据策略从源服务器拉取文件,以保证用户能尽早访问到最新的文件内容。
那么cdn何时会去源服务器取内容呢?事实上,这个策略和浏览器缓存非常类似,我们知道,http 1.1通过cache-control的max-age头可以告知文件在浏览器的缓存时间,在max-age指定的时间内,浏览器会直接使用本地缓存,而不会请求服务器,cdn采取了类似的机制,你只要把cdn节点看成浏览器,源服务器看成浏览器需要请求的服务器即可,此时,源服务器的max-age头决定了资源在cdn节点本地缓存的时间,有一点差别的是,cdn规定了一个自定义协议,s-maxage,若源站该header存在,会优先使用该header作为缓存时间:
Cache-Control:max-age=0, s-maxage=86400
举个栗子解释下cdn缓存策略:
为了避免干扰,我们假设例子中说的cdn只有你一个人在访问。
源站的max-age设定了缓存时间为3600秒,即一小时,cdn的max-age设定了缓存时间为315360000秒,即10年,那么用户首次访问该cdn的文件a.js?v=1时,cdn节点发现本机没有该文件的缓存,会去源服务器取,接下来该文件会在cdn节点缓存3600秒,cdn节点带上自己的max-age头(315360000)返回到浏览器,接下来用户之后10年内访问同一个a.js?v=1不会再发请求(非刷新情况下,且用户侧缓存假设不清除)。
若用户在一小时之内刷新a.js?v=1,意味着该请求会进到cdn服务器,此时服务器发现该url的缓存还没过期(在3600秒内),不会去源站请求,直接返回服务器内容,根据请求header的last-modified(ctrl+f5不带,f5和回车带)决定是吐出304还是200。
若用户在一小时之后刷新a.js?v=1,意味着该请求会进到cdn服务器,此时服务器发现该url的缓存已经超过了3600秒,于是会去源站请求一次,源站会根据请求header的last-modified(ctrl+f5不带,f5和回车带)决定是否吐出304还是200,并把源站的响应直接吐出到浏览器。
对于这个例子,用户侧最坏的情况是10年不请求新版的js,那么怎么解决这个问题,想必大家也知道了,就是加版本号(比如时间戳,可参考此文),因为无论是浏览器缓存还是cdn的缓存,其缓存的key都是get请求,而不只是文件名,因此若a.js变成a.js?v=2,无论是浏览器还是cdn,都会去上一级网络拿取更新的资源。
对于不适合加版本号的页面,比如html文档,此时源站的max-age就要设短一点了,比如设置成1小时,那么再坏的情况下,cdn也会在1小时候回源拿取新的内容,如果想快点生效,需要使用cdn的缓存清理API或工具。
另外可以通过age头查看该资源在当前cdn节点已缓存了多久:
Age: 1921
X-Cache: HIT TCP_MEM_HIT dirn:5:277366080
比如这个例子说明已缓存1921秒。
CDN缓存和浏览器缓存之间的关系
参考:聊聊 CDN 缓存与浏览器缓存
回源和回源比
- 什么是回源?
网上查了下资料,回源大致是指浏览器在发送请求报文时,响应该请求报文的是源站点的服务器,而不是各节点上的缓存服务器,那么这个过程相对于通过各节点上的缓存服务器来响应的话就称作为回源。回源的请求或流量太多的话,有可能会让源站点的服务器承载着过大的访问压力,进而影响服务的正常访问。
- 如何计算回源比?
其实回源比和缓存的命中率正好相反,回源比高,说明缓存系统的缓存命中率低。回源比分为回源请求数比例和回源流量比例两种。
回源请求数比例:收集所有边缘节点上的请求记录,没有缓存或缓存过期的请求以及不可缓存的请求均被作为回源请求,发往源站点服务器响应。其他的请求则由缓存系统直接使用缓存响应。其计算公式为:回源请求数/(回源请求数+用户发送的请求数)
。
回源流量比:即用户所产生的流量当中,有多少流量是直接有源站点服务器响应的,其计算公式为:回源流量/(回源流量+用户请求访问的流量)