This post was published in 2020-12-31. Obviously, expired content is less useful to users if it has already pasted its expiration date.
2022-12-04补充:
来自 🔗 [个人博客CDN选型和进阶玩法指北 | NekoDaemon's Blog] https://nekodaemon.com/2021/08/12/个人博客CDN选型和进阶玩法指北/
更令人智熄的是,基本上个人博客可以和访问量大不到哪去画个等号,你的网站被挤出Cache可太正常了,Cache Miss一下延迟就更爆炸了。无脑上CDN后发生的大概率事件就是CDN打不过三网直连的24块钱的腾讯云香港。
https://nekodaemon.com/2021/08/12/个人博客CDN选型和进阶玩法指北/
得出的结论是:
- 这是一个普遍现象(指CDN缓存过期)
- 普通用户真的很难去抗衡CDN大厂的黑盒策略
下面是原文:
好吧...这是一个某种程度上接近黑盒甚至玄学的问题,甚至没有什么意义:谁会去天天仔细检查那1%的缓存丢失率呢?
随着Cloudflare免费CDN服务逐渐流行,wordpress cache插件也开始向这方面靠拢———于是就有了WP Cloudflare Super Page Cache,尽可能最大化利用Cloudflare提供的edge cache服务。
在理想情况下,我们希望一个站点sitemap.xml里的任意一个链接内容,都被提前缓存在Cloudflare Edge Cache里。看起来很容易是吗?写一个遍历sitemap的脚本,把所有链接都爬一遍,这样它们就能缓存在Cloudflare里了。
然而事实上可能并非如此。Cloudflare的edge cache服务并没有透明地公开具体规则(至少我不知道免费版怎么获得),它有保证你的缓存内容100%全球可用吗?可能未必是这样。比如你在Cloudflare上面一次性preload缓存了100个链接的html文件,结果过了一段时间(没有超过Edge Cache TTL)发现其中有5个链接的缓存丢了。
见:Cloudflare won't cache page via CURL request
根据一些网友的看法,Cloudflare内部有一套复杂的黑箱规则来判断、安排CDN Cache的状态。缓存内容在Edge Cache Expire TTL期间丢失的背后可能有非常多的因素影响:链接的热度、获取链接的request header、获取链接的地理位置、搜索引擎的爬取、fallback TTL的命中...等等。
有什么办法让Cloudflare尽可能长时间的保存preload的缓存内容吗?好吧,至少从我的测试结果来看,把常规的php cURL preload改成puppeteer headless chrome,可能会让缓存内容更不容易被Cloudflare清除。用其他方法可能也可以,总之就是:尽可能把preload的程序伪装成真人,这样Cloudflare可能就会“放过你的缓存一马”。你可以假想一下,用了一些更高级的伪装手段preload网站以后,Cloudflare的内部机制把你的缓存标记为“70% human”,然后你的缓存就能保存的更久一些...
更进一步的伪装方式?见:Making Chrome Headless Undetectable。但目前对我而言,puppeteer已经够用了,只需要一天跑1~2次就能降低preload缓存被丢失的概率。
如果抛开理论,从实用角度出发,WP Cloudflare Super Page Cache提供了一个Fallback Cache功能:页面文件不仅在Cloudflare上保存一份,还在服务器磁盘上缓存一份(就是wordpress传统缓存插件做的事情),如果一个页面在Cloudflare缓存上找不到,就会自动使用服务器里缓存的文件。
这样就可以近似完美地规避Cloudflare丢失缓存的问题了。
后记:本博客最终选择了NGINX FastCGI作为页面缓存方案。