关于七牛CDN缓存问题的处理方式
发布于 8 年前 作者 CN-Sean 16855 次浏览 来自 分享

第一次在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_prefixv20160331这样的变量,每次发布都变化一个就形成了路径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-renamegrunt-replacegrunt-usemingrunt-rev等等。具体就需要大家自行探索啦~

综上, 我会更倾向于第三种方案。(偷偷看看Teambition,也是这种方式~)。

本文来自:http://www.shaowenwu.cn/qi-niu-cdnhuan-cun-wen-ti-de-san-chong-jie-jue-si-lu/

8 回复

cnode也是用的七牛,用的第三种方式。第一种 querystring 的方式,坑多,不建议静态资源使用 querystring 做更新区分。

能不能先删除,再上传 1,以前的文件留着也没有用。 2,重新生成文件名称,也是新增,不如直接增量上传,上传前先删除以前的文件,(未修改过的文件不删除,也不上传)不知道这种方式能不能行的通!

@1021683053 这种不能立即生效的, 我试过一个小时后访问仍然是旧资源.

@yinxin630 好坑,还有种方式调用刷新接口,不过这种方式,资源少还好,多了,就不行!不过还是有缓存时间!

我也选择的第三种,毕竟冗余的文件放在七牛也不额外收费…

回到顶部