Files
blog/EdgeOne双区域方案评估.md
T
zqlit e0218b42bb docs: 迁 CNB 前的架构决策文档 + 构建骨架
- 决策文档:架构总览 / 代码源与构建平台选型 / CNB构建落地方案 /
  EdgeOne双区域 / Gitee / 阿里云ESA / 精简方案
- CNB 构建骨架:deploy/Dockerfile、bin/linux/hugo
  (84MB,linux/amd64 extended 0.128.2,供 CNB 容器 COPY 用)
- scripts/setup-cnb-remotes.sh:双远端切换(CNB 主仓 + GitHub 备份)
- .gitignore 补 .workbuddy/(工作数据不入库)
2026-10-04 12:40:17 +08:00

11 KiB
Raw Blame History

EdgeOne 双区域方案评估

2026-10-04 · 针对「境外用 EdgeOne 国际站、境内改用 EdgeOne 国内站」的构想 以及「write-server 拆成后端服务 + 前端与 blog-admin/Worker 合并」的可行性

一、结论先说

方案成立,而且比 Cloudflare 方案好。 三个理由:

  1. 不违反任何服务条款 —— CF 要加速国内只能走「优选 IP」那条明文违规的路,EdgeOne 是正规产品能力。
  2. 国内速度是量级差异 —— 备案域名的 EdgeOne 大陆节点实测 50–90ms;你现在 CF 后端实测 750ms(差 8–10 倍)。
  3. 你已经在用了 —— deploy-edgeone job 现在就部署在这上面(edgeone pages deploy --area overseas),迁移成本接近零。

而且我发现了你可能没注意到的一件事:EdgeOne Pages 有个 --area 参数,你现在用的是 --area overseas(主动排除了中国大陆)。这可能意味着你只要改一个参数就能达到目的,而不必新建一个项目。详见第三章。


二、你的备案状态(关键前提,已核实)

  • 站点页脚:鄂ICP备2022015735号-1
  • 官方文档明确:当项目的加速区域为「中国大陆可用区」或「全球可用区(含中国大陆)」时,添加的域名必须完成 ICP 备案
  • 你的域名已备案 → 具备启用大陆节点的资格 ✅

这一条是整个方案成立的地基。反过来说,如果没备案,这条路直接堵死(只能用海外节点,国内 670–1400ms)。


三、★ 关键发现:--area 参数

EdgeOne Pages 的 CLI 部署命令带一个区域参数:

参数 含义
--area overseas 只覆盖境外,不含中国大陆 ← 你现在用的就是这个
-a global 覆盖全球 + 中国大陆(需备案域名绑自定义域名)

也就是说,你现在这个 hugo-blog 项目是刻意把大陆排除在外的。于是有两条路:

路 1(最省):单项目改参数

把 CI 里那一行改成 -a global,一个项目、一套配置、一个 token,同时覆盖境内外。

  • 好处:零新增组件,改动只有一个参数
  • 风险:境外质量可能下降。有多位站长实测反馈,global 模式下「海外就差点意思,只有一个节点,走 Anycast 网络」——这可能正是你当初选 overseas 的原因
  • 必须实测:改完之后用境外节点测一次,别只看国内变快了

路 2(你提的):双项目

  • 国际站项目(console.intl.cloud.tencent.com,免备案)→ --area overseas,保境外质量
  • 国内站项目(console.cloud.tencent.com,需实名+备案)→ -a global,保大陆速度
  • 两个控制台、两套 token、两次部署

⚠️ 一个待实测的疑点:官方文档里,国际站的 Pages 与国内站的 Pages 对「大陆节点」的支持描述互相矛盾(国际站文档说 -a global 含大陆,产品介绍又说国际站不含国内节点)。结论不明,必须自己测一次。测法见第七章。


四、EdgeOne Pages 免费额度(官方定价页)

项目 免费额度 你的用量 够吗
安全加速流量 不限 — ✅
安全加速请求数 不限 — ✅
构建次数 500 次/月 约 60–90 次 ✅
Edge Functions 请求 300 万/月 — ✅
Cloud Functions 请求 100 万/月 — ✅
KV 存储 1 GB — ✅
站点数 1 个主域名 + 200 子域名 — ✅
超出用量 收费版推出前不中断服务 — ✅

唯一的硬限制(重要):

单文件、单线程限速 4 Mbps(约 500 KB/s) —— 多位站长实测确认,官方未披露。

要正确理解它:

  • 是单文件单线程限速,不是整站带宽限速。并发请求互不影响
  • 你的 zql-v2.woff2 字体 1.2 MB → 首次加载约 2.4 秒(之后走缓存,不再走网络)
  • 那 7 个 mp4 里最大的 12.8 MB → 首次加载约 25 秒(这是这个方案最实际的痛点)
  • 腾讯云自家 CDN 也有这个限制,属地是「免费套餐的取舍」,不是 bug

如果视频是核心内容,这一条要认真权衡;如果只是少量点缀,影响可控。


五、能砍掉什么

对比现在的架构(EdgeOne 国际 + 又拍云 + 多吉云 + 广州中转机 + sync.sh 轮询):

组件 现架构 EdgeOne 双区域
境外 CDN EdgeOne 国际站 EdgeOne 国际站(不变)
境内 CDN 又拍云 + 多吉云 EdgeOne 国内站
产物搬运 广州中转机 + sync.sh 每分钟轮询 删除
产物中转 腾讯云 COS 已砍(进行中)
凭据面 又拍云密码 + 多吉云 SK(明文写在 sync.sh) 删除
厂商数 EdgeOne + 又拍云 + 多吉云 + 腾讯云 COS 腾讯云一家

净收益:少 2 家厂商、少 1 台常驻机器、少 1 个每分钟跑的轮询脚本、少 2 套硬编码凭据。 发布链路从 7 环节降到 4 环节(写作 → 构建 → 双区域部署 → 通知)。


六、write-server 拆分评估(你问的第二件事)

6.1 结论:技术可行,而且必须拆才能上边缘平台

这不是"能不能"的问题,而是只能这样。EdgeOne Pages(和 CF Workers 一样)的运行时限制是硬的:

  • 无持久化文件系统 —— 无法读写 content/ 下的 .md
  • 不能执行 git —— 无法 git pull/push
  • 单次函数执行有超时(通常 30s)

而 write-server 的核心恰恰是这两件事:读写本地 md 文件 + git 操作。

6.2 现状的耦合点(已扫描)

write-server/src/
  app/{edit,login,posts,images,links,feeds,comments,users,bot,wechat}/   ← 页面(可上前端)
  app/api/                       ← 23 个 API 路由
  lib/
    posts.ts    ← fs 读写 md          ⛔ 必须留后端
    git.ts      ← child_process git    ⛔ 必须留后端
    hugo.ts     ← 调 hugo 二进制        ⛔ 必须留后端
    recycle.ts  ← fs                    ⛔ 必须留后端
    auth.ts     ← fs(用户表)          ⛔ 必须留后端
    bot/*       ← 子进程轮询            ⛔ 必须留后端
    ai.ts / artalk.ts / rssapi.ts / wechat.ts / fetch.ts   ← 纯 HTTP(可两边)

好消息:页面与 API 已经分得比较清楚,src/lib 里哪些能上边缘、哪些必须留后端,界限是清晰的。这不是一个烂摊子。

6.3 拆分后的形态

前端(EdgeOne Pages / CF Worker)
  React SPA(由现有页面改造)+ 调用后端 API
        │
        ▼
后端(一台有文件系统的服务器)
  Node 服务 + 复用现有 src/lib(几乎不用改)
  → 读写 md、跑 git、调 hugo、发 RSS

必须改的四件事:

  1. 认证:现在是同域 session/cookie,分离后要改成 token(Bearer / JWT)+ CORS
  2. 数据获取:服务端组件直读 md → 改成客户端 fetch API(多一次往返,但要加 loading 态)
  3. 图片上传:写本地磁盘 → 改成对象存储(又拍云 / R2 / EdgeOne KV)
  4. API 地址配置化:src/lib/config.ts 里加后端 base URL

6.4 ⚠️ 但先问一句:为什么要拆?

如果目的是**"一个统一的管理入口"(体验问题),那拆分会让架构变复杂**——从 1 个应用变成 2 个(前端 + 后端),组件数不减反增。这跟你要的"简化"是反方向。

更省的做法(零重构):用一个域名 + 路径分流把两个后台挂在一起。

admin.usj.cc/            → blog-admin(CF Worker,评论/RSS 管理)
admin.usj.cc/write/      → write-server(写作后台)

三种实现,任选:

  • OpenResty 反代(你国内机已经有):加几行 location /write/ { proxy_pass ...; },成本最低
  • EdgeOne 规则引擎:用 URL 重定向 / 路径规则做分流
  • CF Worker 薄代理层:能做,但 CF 国内慢,不适合做入口

判断标准:

  • 只要"一个入口" → 反代,别重构
  • 真的需要"前端独立部署到边缘、后端瘦成纯 API" → 才做拆分,且要接受工作量和组件数增加

七、建议的推进顺序

第 0 步(今天就能做):一次实验,验证单项目可行性

这是成本最低、信息量最大的一步,只需改一个参数:

# 用已有的 token,把产物部署到 global 区域(覆盖大陆)测一次
npx edgeone pages deploy ./public -n hugo-blog -t "$EDGEONE_API_TOKEN" -a global

然后用国内机实测(可复用我之前写的 probe_speed.py 那套):

  • 大陆解析到的 IP 是不是国内 IP
  • TTFB 是否降到 100ms 级

如果单项目 -a global 就达标 → 方案收敛为「改一个参数」,收工。 如果不达标或影响境外 → 再走双项目。

第 1 步:确定区域策略

根据第 0 步结果,二选一:

  • 单项目 -a global
  • 双项目(国际站 + 国内站,两套 token)

第 2 步:接上大陆域名

国内站的 Pages 项目绑定自定义域名,走 ICP 备案校验(你已有备案号)。

第 3 步:砍掉旧链路

确认 EdgeOne 双区域稳定运行 1–2 周后,再依次停掉:

  • 广州中转机的 sync.sh 定时任务(1Panel 里 id=15 那个每分钟的)
  • 又拍云、多吉云的同步逻辑
  • deploy.yml 里对应的通知与检查步骤

不要跳步,也不要和"write-server 重构"混在同一次变更里。

第 4 步(可选,独立评估):write-server

先回答 6.4 那个问题。如果要拆,它是一次独立的重构工程,单独排期。


八、待核实项(我标出来,不装作确定)

# 事项 状态 怎么验
1 国际站 Pages 的 -a global 是否真能启用大陆节点 文档矛盾,待实测 第七章第 0 步
2 --area overseas 当初是否是刻意选择(境外质量考虑) 待你确认 问你自己
3 500KB/s 单文件限速对 7 个 mp4 的实际影响 已知限制,待评估 测一个最大视频的首字节
4 国内站的备案接入校验是否需要变更接入商 待核实 绑定域名时会暴露
5 EdgeOne Pages 的 Git 集成是否支持 Gitee 有第三方提到,未官方确认 若支持,可再砍掉 Gitea + act_runner

第 5 条如果成立,价值很大:Gitee 是国内平台,用它的 Git 集成自动构建, 就能把自建 Gitea + act_runner + 中转机整条链一起砍掉。但需要先确认支持情况。


九、一句话总结

你的方向是对的,而且比 CF 方案好——不违规、快 8–10 倍、你已经在用了。 但在动手建第二个项目之前,先花十分钟做第七章那个「改一个参数」的实验。 它可能直接告诉你:这件事根本不需要两个项目。