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秒。

参考资料:http://baike.corp.taobao.com/index.php/CDN-Usermanul?spm=0.0.0.0.wxN22z

posted @ 2017-05-27 10:12 quincyWang 阅读(...) 评论(...) 编辑 收藏