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

235 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 步(今天就能做):一次实验,验证单项目可行性
这是**成本最低、信息量最大**的一步,只需改一个参数:
```bash
# 用已有的 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 倍、你已经在用了。**
**但在动手建第二个项目之前,先花十分钟做第七章那个「改一个参数」的实验。**
它可能直接告诉你:**这件事根本不需要两个项目。**