Cloudflare图床缓存优化
折腾了几个小时,终于把 Cloudflare 图床的 KV 读取次数降下来了
先说说为啥要搞这个
前段时间用 Cloudflare Pages + Workers + KV 搭了个图床(就是 GitHub 上那个 Cloudflare-ImgBed),一开始挺美滋滋的,免费嘛。
结果用了一个多月,突然收到 Cloudflare 的邮件,说我 KV 读取快超限了。我一看后台,好家伙,一天干了 9 万多次读取,离 10 万次的免费额度就差一口气。
这哪行啊,虽然超了也花不了几个钱,但本着「能白嫖绝不付费」的原则,得想办法优化一下。
问题出在哪
仔细看了下流程,每次有人访问图片:
1 | 用户请求 → Worker 验证 → 读 KV → 从 Telegram 拉图 → 返回 |
关键是每次访问都走完整流程。同一张图被看 10 次,KV 就得读 10 次,Telegram 也得拉 10 次。太浪费了。
明明图片这种东西,第一次拉下来之后完全可以缓存起来啊。
我的解决方案
思路其实很简单:加缓存。
1 | 用户 → Cloudflare CDN 缓存 → Worker 内存缓存 → KV/源站 |
理想情况是:第一次访问走完整流程,后面再来就直接从 CDN 返回,Worker 都不进。
代码实现
Cloudflare Pages 有个 _middleware.js 的机制,可以在请求返回前插手改响应头。
在项目创建了 /functions/_middleware.js 这个文件,内容如下 嘻嘻😋
1 | // /functions/_middleware.js |
怎么验证生效了没
打开浏览器 F12,Network 标签,找个图片看看响应头:
- 看到
cf-cache-status: HIT说明 CDN 缓存生效了 - 看到
age: 114514说明这张图已经被缓存了 114514 秒 - 如果
cf-cache-status一直是 MISS,那说明哪里没配对
用命令行验证更准确:
1 | # 第一次请求(应该 MISS) |
效果咋样
说实话,我也没有精确统计。
但有个很直接的证据:自从上了缓存,Cloudflare 再也没给我发过那封让人窒息的「你的 KV 额度快用完了」的邮件。
而且有次我特意看了下响应头,发现一张图片的 age 已经到 21 小时了,说明这张图在一天内被访问了几十次,但只从我的源站拉了一次,剩下的全都从 CDN 直接返回。KV 读取从每天几千次降到了几百次。
如果你也想搞
几个小建议:
- 别啥都缓存,只缓存图片就行,API 接口啥的别动
- 缓存时间自己把握,我设的 7 天,热门图重复访问基本都命中
- 别搞太复杂,我就走了弯路,写了一大堆缓存逻辑最后全删了,只用几行代码加个响应头就搞定了
- 监控一下,Cloudflare 后台的 Workers & Pages 页面能看到请求数和缓存情况
参考链接
贴几个我查资料时看的页面:
- Cloudflare Cache API 文档 - 官方文档,有点干
- Workers KV 定价页面 - 看了才知道免费额度其实挺少的
- 这篇博客 - 有人总结了 Workers 优化的 7 个技巧,挺实用
最后说一句
其实回过头看,解决方案比我想象的简单得多。本来以为要动很多代码,结果就加了十几行,还删了一堆。有时候最简单的方案就是最好的方案。
大概就是这样,没了。
