该博客 码厩(markjour.com) 是一个全静态的站点,部署在阿里云的虚拟主机上。
静态网站最大的优点就是省心,完全不需要什么维护工作,写完文章(Markdown 格式)之后编译(HTML 格式)、上传即可,这个过程是通过自己开发的一个 Python 工具实现的。
但是最近几个月遇到了一个比较头疼的问题:几乎每到月底,最后几天网站无法访问,阿里云那边说是本月流量已超出限制。
以前几年一直没遇到过,流量也没有明显变化,不知道是不是最近调整了统计规则。总之,隔三差五地无法访问就很糟糕。
今天抽空处理一下,我想着将网站使用的一些公共资源 —— 如 Bootstrap、jQuery、Font Awesome 等 —— 都采用前端公共资源 CDN,应该就好了。
PS:其实一开始是采用了前端公共资源 CDN 的,只是因为之前选的那些 CDN 用不了多久就关门了,所以就拿掉了。现在又出现这个问题,没有办法,只好重新采用 CDN 的方案。
写了一个一键切换 CDN 的脚本
我的博客采用模板编译生成页面,因此引用前端静态资源的地方比较集中。
我写了一个简单的映射脚本,根据我选择的 CDN 自动 replace 模板文件中的前端静态资源路径就好了。
cdn_provider = {
'bootcdn': 'https://cdn.bootcdn.net/ajax/libs/%(name)s/%(version)s/%(path)s',
'cdnjs': 'https://cdnjs.cloudflare.com/ajax/libs/%(name)s/%(version)s/%(path)s',
}
chosen_cdn = 'cdnjs'
然后重新编译上传就好了。
重点还是 CDN 的选择。
一开始选择了 BootCDN
国内做公共静态资源 CDN,第一个想到的自然是 BootCDN。
-> % dig +noall +answer cdn.bootcdn.net
cdn.bootcdn.net. 11 IN CNAME cdn.bootcdn.net.d48437e9.cdnhwcvix16.com.
cdn.bootcdn.net.d48437e9.cdnhwcvix16.com. 11 IN CNAME hcdnw101.sme.foreignv6.cdnhwcaoc115.cn.
hcdnw101.sme.foreignv6.cdnhwcaoc115.cn. 11 IN A 117.187.133.33
hcdnw101.sme.foreignv6.cdnhwcaoc115.cn. 11 IN A 112.46.240.47
简单调研了一下,它现在背后采用的是华为云 CDN。
在 DNS Checker 等工具上查看了一下,发现这个 CDN 是做了海内外区分的,想必在其他国家访问也不会有什么问题。
结果测试的时候发现了一个让我非常疑惑的问题。
BootCDN 居然不给浏览器缓存
检查 HTTP 响应头的时候发现:
cache-control: no-cache, no-store, must-revalidate
这是明确告诉浏览器不要缓存:
no-cache必须从服务器获得 304 之后才可以使用缓存(If-None-Match / If-Modified-Since)no-store关闭浏览器缓存must-revalidate缓存失效以后需要重新请求
对于公共静态资源来说,这几乎是最糟糕的缓存策略。用户使用体验差、回源压力大、流量消耗大。
一个前端公共资源 CDN 主动关闭浏览器缓存,真不知道他们出于什么考虑,费解!
完全没有必要禁止浏览器缓存,静态资源版本发布之后又不会变动了,完全可以用一个月甚至一年的缓存时间。
按照正常情况,CDN 应该这样返回才对:
Cache-Control: public, max-age=31536000, immutable
ETag: "..."
Last-Modified: "..."
最终还是切到了 Cloudflare 的 cdnjs
既然 BootCDN 在缓存策略上让我无法接受,那最后还是回到了赛博佛祖 Cloudflare 的怀抱,采用 CDNJS:
返回的头就没有问题:
cache-control: public, max-age=30672000
last-modified: Fri, 11 Feb 2022 00:01:04 GMT
expires: Thu, 17 Jun 2027 04:03:00 GMT