第一次在CNode上分享一下自己的经验,求高手们指教~
在生产部署中,由于图片等资源文件的体积较大,容易占用掉服务器的带宽,通常我们会选择使用CDN
来解决我们的问题。让CDN节点从服务器同步资源文件,然后进行分发。接下来,讲一下我自己使用CDN的一些感受。以七牛云为例。
问题
CDN的结构大致如上图。那么问题来了,我们把Bucket
作为每个CDN节点的回源
。既然CDN节点已经从源里同步了资源,那么如果源里的文件更新了,又如何让节点里的内容也同样更新呢?一种是主动更新,也就是缓存刷新
,七牛里可以通过管理员后台进行指定路径的刷新操作,如下图:
但是这种方式,对于用户而言,仍然有本地浏览器的缓存会导致无法获取到最新的资源文件,而且这种刷新机制并不是立即可以生效的。所以我们不得不采取其他方式。七牛官方有给出一些方案,可参考官方文档。这里,我们主要看通过url来刷新缓存的方式。
实践
首先,假设某文件资源路径为http://bucket.qbox.me/css/index.css
。
通过url修改的方式来刷新缓存的方式有以下三种:
1. url后加参数
比如每次新版本发布了,我们都在js,css和图片等请求路径后面加上?v=20160331
这样子的动态参数,形成http://bucket.qbox.me/css/index.css?v=20160331
来强制让CDN节点重新从源进行同步,获取需要的新文件。
优点
这是3种方式中,最简单的一种。
缺点
稳定性差。经过一段时间的线上实践,我已经感觉到了这种方式有时候也会存在问题。
讲一段亲身经历,在阿里钉钉
的集成开发中,这种方式似乎无法保证每次都可以从路径中准确地获取到资源,作为一个SPA
的应用而言,没有加载到js资源的话简直就是噩梦。无数次,钉钉手机客户端一更新,用户重新打开我们的应用,资源文件就加载不到了,我不得不再次修改路径后的动态参数,强制重新获取。后来发现删除钉钉app,重新安装也可以解决这个问题,于是不得不猜测钉钉的webview
里的缓存机制也许是个坑
,至少对于这种修改url后参数的方式不适用吧。没有深究,因为这个问题,无法稳定还原,只是常常有用户遇到。
2. 前缀变更
比如本地工程的所有资源文件在public
目录下,在我们使用qrsync
与bucket进行同步时,设置路径前缀key_prefix
为v20160331
这样的变量,每次发布都变化一个就形成了路径http://bucket.qbox.me/v20160331/css/index.css
。
优点
稳定性好。
缺点
无法增量更新。qrsync是一种增量更新的机制,如果每次发布都要修改路径前缀,就意味着所有需要放CDN的资源文件,无论是否被修改过,都要重新被同步到bucket的新的路径下。也就是必须全量更新。在使用qrsync的时候,需要手动删除机器的~/.qrsync
目录下的备份数据。这样才能执行全量更新。如果图片超多的话,这种全量更新的方式,你懂得~
3. 文件md5重命名
这是一种用的比较多的方式,在我们使用打包工具打包的时候,可以把最后压缩得到的css和js重新定义一个名字,与此同时替换掉html里定义的路径。于是可以得到类似http://bucket.qbox.me/css/index.6cff2dcd.css
的路径。与第二点有点相同,都完全改变的路径。
优点
稳定性好。
支持增量更新。很明显,路径前缀没有变化,打包的时候,只有被修改的文件,才会重新获得一个md5。因此,只有被修改的文件才需要更新。
缺点
打包麻烦。这一点,其实不需要太在意,毕竟部署这种事情,配置好了很多情况都会一劳永逸
,做过运维的都懂~
grunt
里可以用的插件有grunt-rename
、grunt-replace
、grunt-usemin
和grunt-rev
等等。具体就需要大家自行探索啦~
综上, 我会更倾向于第三种方案。(偷偷看看Teambition
,也是这种方式~)。
本文来自:http://www.shaowenwu.cn/qi-niu-cdnhuan-cun-wen-ti-de-san-chong-jie-jue-si-lu/