jxe.me跑在 Cloudflare Workers 上,图片视频全存在 R2,用 R2 自定义域名 r2.e.jxe.me 直连访问。问题很现实:国内访问 Cloudflare 的速度全看运气,一张 500KB 的图 TTFB 经常 1.4~2.2 秒,抽风的时候直接超时白屏。

这篇记录我用腾讯云 EdgeOne 给 R2 套国内 CDN 的完整过程,包括那个卡了我很久的 418 拦截坑。最终效果:边缘节点命中缓存,TTFB 稳定在 0.3 秒左右。

[!note]
环境前提:R2 桶已绑定一个可正常访问的自定义域名(本文以 r2.e.jxe.me 为例),EdgeOne 回源就指向它。不需要改 R2 里的任何东西,也不需要换桶。

一、整体思路

Cloudflare 在国内没有节点,而 EdgeOne 在国内有机房。让国内用户访问 EdgeOne 节点,EdgeOne 再回源去 Cloudflare 的 R2 域名拉取:

访客 → EdgeOne 国内节点(命中缓存直接返回)
              │ 未命中时回源
              ▼
     r2.e.jxe.me(Cloudflare R2 自定义域名)

只有第一次请求(或缓存过期)才需要回源,之后都由 EdgeOne 边缘直接返回。R2 侧完全无感。

二、接入步骤

1. 准备一个已备案域名(最关键的前提,先看第四节的坑)

EdgeOne 自定义加速域名必须使用已在中国大陆备案的域名。我主域名 jxe.me 没有备案,所以用了另一个在阿里云备案的域名 ymao.me,加速域名取 r2.ymao.me。

备案接入商和 EdgeOne 不要求是同一家(我的备案在阿里云,照样能接腾讯)。

2. EdgeOne 控制台添加站点

登录 EdgeOne 控制台,新增站点,填入备案域名 ymao.me,接入方式选 NS 接入(按提示把域名 NS 改到 EdgeOne 分配的 NS 服务器)或 CNAME 接入均可。NS 接入后 DNS 解析也托管在 EdgeOne,后续加子域名比较省事。

3. 添加加速域名

在「域名服务 → 域名管理」里添加加速域名:

  • 加速域名:r2.ymao.me
  • 源站类型:域名
  • 源站地址:r2.e.jxe.me(你的 R2 自定义域名)
  • 回源协议:HTTPS
  • 回源 HOST:r2.e.jxe.me ← 这一项非常重要,必须和源站地址保持一致

为什么回源 HOST 不能乱填? R2 自定义域名是靠请求的 Host 头来路由到具体桶的。如果回源 HOST 被默认改成加速域名 r2.ymao.me,Cloudflare 那边根本不认识这个 Host,回源必然失败。这也是很多教程没讲清楚的一点。

4. 等待证书签发与节点生效

开启 HTTPS(EdgeOne 提供免费证书),添加后等几分钟到几十分钟,状态变为「已生效」。再到 DNS 确认 r2.ymao.me 的 CNAME/A 记录已正确生成。

5. 验证

看响应头,出现 EO-Cache-Status: HIT 就说明边缘命中了:

curl -I http://r2.ymao.me/uploads/images/xxx.jpg
HTTP/1.1 200 OK
Content-Type: image/jpeg
EO-Cache-Status: HIT
Cache-Control: max-age=14400
Content-Length: 552280

第一次请求可能是 MISS(回源拉取),再刷一次变 HIT 就对了。

三、实测对比

同样一张图,不同链路的 TTFB:

| 链路 | TTFB | 稳定性 |
|---|---|---|
| Cloudflare R2 直连(r2.e.jxe.me) | 1.4 ~ 2.2s | 抽风,偶发握手失败 |
| EdgeOne 边缘命中(r2.ymao.me) | 0.31s | 3/3 全部成功 |

推荐两个免费拨测工具,避免「本机网络好就以为全国都好」:

  • check-host.net:全球多节点 HTTP 检查,适合判断是不是平台级拦截(418 那次就是靠它实锤的)
  • IT 狗 itdog.cn:国内各省市节点拨测,看全国访问速度和缓存命中情况

四、踩坑记录

坑 1(最大的坑):未备案域名全球 418

一开始我想偷懒,直接拿没备案的测试域名 r2.jxe.me.eo.dnse4.com(EdgeOne 分配的测试地址)来测,结果浏览器打开是一个空白错误页:

418 错误

我一度以为是自己配置错了,按顺序排查了一圈:

  1. 回源 HOST 错误? —— 改成源站域名后问题依旧,排除;
  2. 安全/WAF 规则拦截? —— 把托管规则调成「观察模式」,仍然 418,排除;
  3. IPv6 问题? —— 强制 IPv4 访问一样 418,排除。

最后用 check-host.net 全球 5 个节点拨测,全部返回 418,耗时只有 0.02~0.17 秒,响应 IP 全是腾讯的节点。请求根本没有离开 EdgeOne 平台就被拒了——这是 EdgeOne 对未 ICP 备案域名的平台级拦截,全球所有节点生效,不是地区策略,也不是你配置的问题。

换已备案的 ymao.me 重新接入后,立刻就通了。

坑 2:「官方说不备案也能用」—— 那是 EdgeOne Pages,不是 CDN

排障时我查到官方文档确实写着「不备案也可以使用」,差点怀疑人生。仔细一看,那说的是 EdgeOne Pages(静态托管,分配 *.edgeone.app 域名)的场景。

  • EdgeOne Pages(xxx.edgeone.app):不备案可用;
  • EdgeOne CDN 自定义加速域名:全球校验 ICP 备案,未备案一律 418。

两个产品同名「EdgeOne」,文档容易串,注意区分。

坑 3:本机测速严重失真

我用家里的移动宽带直连测试,Cloudflare 和 EdgeOne 的 443 端口都频繁 TLS 握手失败,一度以为 EdgeOne 也挂了。后来发现是本地宽带对 443 的国际链路极不稳定。

经验:

  • 判断服务是否正常,用线上拨测工具(check-host / itdog),别只信本机;
  • 排查阶段可以先用 curl -I http://域名(80 端口)验证回源与缓存逻辑,通了再查 443 证书。

坑 4:新域名 443 证书未签发完

接入初期可能遇到部分节点 HTTPS 握手失败、HTTP 80 却正常。这通常是免费证书还没在所有节点签发/同步完成,去控制台「证书管理」确认状态为「已部署」,等它全球生效即可。

五、进阶:连随机背景图一起加速

我的博客有个「随机背景图」功能:Worker 定时把图源抓回来缓存进 R2,对象 key 形如 bg/xxxx/时间桶.jpg,以前访客通过 jxe.me/api/bg 由 Worker 流式直出——图片虽然在 R2 里,访问却绕了一圈 Worker,完全没吃到 CDN。

改造思路很小:背景图本来就是 R2 桶里的普通对象,前端直接按 key 拼出 https://r2.ymao.me/bg/xxxx/时间桶.jpg 去拿即可。实测这个对象同样返回 EO-Cache-Status: HIT。

为了稳妥还加了两道保险:

  1. 后台没配 R2 媒体域名时,自动走回原来的 /api/bg;
  2. 直连图片 onerror 时自动回退 /api/bg。

这样就算 EdgeOne 哪天抽风,背景图最坏也就是退回旧链路,不会裂图。顺带一提,站点所有媒体入库时统一只存 key(如 uploads/images/2026-09/xxx.jpg),输出时再按后台配置拼域名——以后换 CDN 只需要后台改一个字段,全站图片秒切,代码和数据都不用动。

六、小结

  • EdgeOne 给 R2 套国内 CDN:源站填 R2 自定义域名、HTTPS 回源、回源 HOST 保持源站域名;
  • 未备案域名一律 418,平台级全球拦截,别浪费时间查 WAF;
  • 「不备案可用」指的是 EdgeOne Pages,不是 CDN;
  • 用 check-host + itdog 验证,别迷信本机网络;
  • TTFB 从 1.4~2.2s 降到 0.3s,体感提升非常明显。