博客 CDN 迁移到 Cloudflare R2

博客 CDN 迁移到 Cloudflare R2

💡 原文中文,约3800字,阅读约需9分钟。
📝

内容提要

作者将博客静态资源从又拍云迁移至Cloudflare R2,因域名DNS已迁至Cloudflare且备案维护繁琐。R2无出口流量费,整合便捷。迁移后通过本地脚本生成WebP并上传,用<picture>兼容格式,配置WAF、热链保护、速率限制和长缓存防刷。放弃GitHub Actions和PicGo,保持本地源图流程,便于未来扩展AVIF等处理。

🔎

延伸解读

迁移动机:备案与整合

作者迁移到 R2 的核心原因并非性能,而是域名 DNS 已迁至 Cloudflare,且国内备案维护繁琐。又拍云方案对备案域名有依赖,继续使用可能面临后续折腾。R2 与 Cloudflare 的整合让静态资源域名不变,历史图片链接无需修改,降低了迁移成本。这提醒读者,选择云服务时需考虑长期维护成本和生态整合。

本地预处理 vs 运行时处理

作者放弃又拍云 URL 参数式的运行时图片处理,改为本地用 sharp 生成 WebP 再上传。这种做法的好处是图片处理逻辑回归项目,不依赖特定云服务,未来扩展 AVIF 等格式更灵活。但代价是失去“一行参数”的便利,需要本地脚本支持。读者可权衡:若图片处理需求复杂且多变,本地预处理可能更可控。

防刷策略:多层限制

R2 虽无出口流量费,但作者仍配置了多层防护:Hotlink Protection 挡盗链,WAF 规则限制请求方法、路径、查询参数和扩展名,Rate Limiting 限制频率,并设置长缓存。这些措施旨在减少无效请求和 R2 读取次数,控制成本。读者可借鉴:即使服务商提供免费出口,也需主动防护以避免资源滥用。

自动化取舍:本地发布更合适

作者曾考虑 GitHub Actions 自动化,但因源图不提交仓库,CI 需从 R2 拉取再处理,反而增加读取操作,最终放弃。PicGo 工具也不适合主流程,因其上传后本地无源图,影响后续处理。这体现了自动化并非总是最优,需根据实际工作流权衡。读者可思考:自动化是否真正简化流程,还是引入额外复杂度。

Q&A

为什么作者要将博客的CDN从又拍云迁移到Cloudflare R2?

作者迁移的原因主要有两个:一是域名DNS已经迁到Cloudflare,二是国内备案维护繁琐,而又拍云的CDN/云存储方案对备案域名有依赖,继续使用可能还需要再折腾。R2与Cloudflare整合方便,且无出口流量费。

Cloudflare R2相比又拍云有哪些优势?

R2的优势在于与Cloudflare的整合,因为域名已经托管在Cloudflare,迁移后对外URL不变,历史文章图片无需修改。另外,R2没有出口流量费,对于小站来说成本较低,但需要注意防刷。

如何确认博客CDN已经成功切换到Cloudflare?

可以通过curl命令检查响应头,如果看到server: cloudflare、cf-ray和cf-cache-status等字段,说明请求已经经过Cloudflare。同时,检查WebP文件的content-type是否为image/webp,以及带query string的请求是否返回403(因为WAF规则拒绝带query string的图片请求)。

迁移到R2后,图片处理方式有什么变化?

以前又拍云支持在URL中加参数进行图片处理(如WebP转换和缩略图),迁移后不再依赖运行时参数,改为本地预处理。源图放在.cdn-source/目录,通过pnpm cdn:publish脚本用sharp生成WebP,再用rclone上传。文章中使用<picture>标签兼容WebP。

作者采取了哪些措施来防止CDN被恶意刷流量?

作者采取了四层防护:1. Cloudflare Hotlink Protection防止盗链;2. WAF自定义规则,只允许GET和HEAD请求,只允许访问/draw/和/img/路径,拒绝query string,只允许图片扩展名;3. Rate Limiting限制每10秒100个请求,并排除Cloudflare verified bots;4. 设置长缓存头(Cache-Control: public, max-age=31536000, immutable),提高缓存命中率。

为什么作者没有使用GitHub Actions来自动化图片上传?

因为.cdn-source/目录是本地目录,不会提交到Git仓库。如果使用GitHub Actions,需要先从R2拉取源图,再处理上传,这会增加R2的读取操作,并不划算。所以作者选择本地发布流程。

PicGo工具在作者的博客图片流程中扮演什么角色?

PicGo适合临时分享图片,但不适合作为博客主流程,因为如果图片直接从PicGo上传到R2,本地.cdn-source/就没有源图,后续的WebP生成、AVIF扩展等处理都会断开。所以作者将PicGo用于临时分享,写博客的图片则先放入.cdn-source/再发布。

迁移到R2后,博客静态资源的架构是怎样的?

迁移后,Cloudflare R2负责存储,Cloudflare CDN/WAF负责分发和防护,本地脚本负责图片处理和发布。图片处理逻辑回到项目中,未来添加AVIF等格式时不受云服务限制。

🏷️

标签

➡️

继续阅读