docs: 全量梳理文档结构;补 Gitea 迁移指南 / 架构精简候选;架构总览补证书管家子系统
用户四问:「把项目文件全部理一遍 还有readme文件」「gitea 后面可能还要迁移 帮我写一个迁移文档」
「证书管家做完了吗」「感觉现在架构还是复杂了」
一、文档梳理:根目录 15 个 md → 2 个
根目录只留 README.md(入口)+ 架构总览.md(现状唯一事实源),其余全部归位:
docs/
├── README.md ← 新增:文档地图(入口 / 当前有效 / 历史归档 三层)
├── 证书管家.md ← 原「函数版证书管家-方案.md」改名
│ (它早已是「现状+沿革」文档,标题名不副实 —— 签发早已不在 CF Worker)
├── Gitea迁移指南.md ← 新增
├── 架构精简候选.md ← 新增
├── CNB构建落地方案.md / GITEA_SECRETS.md
└── archive/{平台与选型,功能与修复,主题与内容}/ ← 32 份
- 32 个归档文档统一加 `> 📦 本文档已归档` banner,并指向架构总览
—— 这个仓库历史文档里全是「权威口径」,混看很容易拿废弃结论当现状
- gitea-backup/ → deploy/gitea/(原名「backup」不准,它是部署包;与其它 deploy 单元并列)
- 新增 md 链接校验(python 脚本,中文路径用 sed 不安全)→ 首轮 18 处断链
(多一层目录要让 banner 里的相对路径补一个 ../)→ 修正后 0 断链
二、新增 docs/Gitea迁移指南.md(★ 有死线:境外 VPS 11 月到期)
★ 核心价值是「指出迁移面已大幅缩小」:仓库原有的 deploy/gitea/迁移前检查清单.md
(2026-10-04)是为「Gitea + act_runner + 又拍云同步 *整套* 搬迁」写的,**那个前提已经不存在**——
构建归 CNB,runner / upyun-sync / 中转机 / COS 都不需要了。迁移实际只剩「搬数据卷 + 改地址」。
★★ 全文最重要:本仓有 9 处写死了旧地址,按易漏程度排序(1-3 本机,4-5 线上)
1 本机 .git/config 的 gitea remote
2 scripts/setup-cnb-remotes.sh 的 GITEA_URL 默认值
3 deploy/editor-api/bootstrap.sh 的 GITEA_URL 默认值
4 ★ /srv/editor-api/.env 的 GITEA_URL ← 漏了会「持续报错但只警告不阻断」,没人发现
5 ★ /srv/blog 的 gitea remote ← 同上
6 docs/GITEA_SECRETS.md
7-9 架构总览.md / README.md / editor-api/README.md
(不用改:docker-compose.editor.yml、server.mjs、pushall 别名 —— 只引用 remote 名字)
另含:建议新实例改用域名而非 IP(以后搬机器只改 DNS;⚠️ Gitea 28 起只读 ROOT_URL 不读
[server] DOMAIN);rsync 而非 dump(属主必须 uid/gid 1000);切换顺序「先建新的→验证→再拆旧的」;
验证清单强调 `git push gitea --dry-run`;第九节给出「干脆不留这个辅仓」的选项与判断依据。
顺带修掉两个硬伤:
- deploy/gitea/docker-compose.yml 的镜像 tag `1.28.0-rootless` 根本不存在
(Gitea 28 起去掉 1. 前缀)→ 改 28.0.0-rootless(pin 死,不用 latest)
- deploy/gitea/.gitignore 漏了 backups/(跑一次备份就会把含 secrets 的 dump 写进历史)
三、证书管家核实(结论:已上线运行,2 个遗留)
线上实测:容器 Up (healthy);/preflight 7/7 全过;3 组域名;下次自动续期 04:10。
遗留 ① writeapi.usj.cc 证书没纳管(真问题):nginx 配置在 /www/conf.d/writeapi.usj.cc.conf,
不在 /www/sites/ 管理树里 → 1Panel 的 ssl/upload+sslID 物化碰不到它。
实测仍是 RSA / CN=usj.cc / 到期 2026-12-07,本项目续期不会更新 → 12 月会断。
遗留 ② dnsapi.usj.cc 没上 HTTPS。
(澄清假问题:200181.xyz 公网看到的 LE 证书是 CF 自家边缘证书,与本项目无关)
四、新增 docs/架构精简候选.md(回应「架构还是复杂了」)
结论:复杂度不在件数,在「跨 6 个环境,其中 4 个要自己维护」。国内机 9 个容器里属于本项目的
只有 3 个,能动的只有 2 个。5 个候选 + 建议执行顺序:
1 停 certimate 容器(工作流已全停用)——先 stop 观察,别急着删
2 cn-dns-helper 大概率已是遗留(「Worker 侧签发」时代产物;现在签发在国内机且自带 dnsprovider,
/preflight 显示 CF 凭据可读;Worker 侧 dnsremoted.ts 已无任何引用)
3 Gitea:迁 or 不留
4 两套写作前端收敛(本轮不动,先看使用频率)
5 writeapi.usj.cc 证书纳管(12 月死线)
并明确列出 6 项「必要复杂度,不建议动」。
五、架构总览补齐证书管家子系统(★ 之前完全缺席)
一个完整子系统在「事实源文档」里一个字都没有 —— 这本身就是文档债。补:
- §0 一句话(四→五个子系统)、§1.1 子系统表、§1.2 地址地图两行
- **新增 §5.7 证书管家**:职责划分 / 为什么非要这么分(Worker 免费版 CPU 10ms)/
三条不能破的红线(Worker 不得签发 · 证书路由只认 Bearer 会话 · 角色必须正着枚举放行)/
纳管域名表 / 与 certimate 的关系 / 已知遗留
- .cnb.yml 行数 284 → 337(数字漂了);头部更新时间 → 2026-10-06;附录表改指 docs/
- §6 待办:#13(证书遗留)、#14(复杂度盘点)新增;#7 改写为「Gitea 11 月到期,★ 有死线」
六、记忆
.workbuddy/memory/MEMORY.md 新增「文档结构」「Gitea 迁移死线」两节;证书管家节补实测与遗留。
This commit is contained in:
1 parent
15a8b502db
commit
1568b150b3
48 files changed
+782
-100
No files matched your search
@@ -0,0 +1,237 @@
|
||||
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的评估与方案**,其中的结论可能已被后续决策推翻。
|
||||
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../架构总览.md)。
|
||||
|
||||
# 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 倍、你已经在用了。**
|
||||
**但在动手建第二个项目之前,先花十分钟做第七章那个「改一个参数」的实验。**
|
||||
它可能直接告诉你:**这件事根本不需要两个项目。**
|
||||
@@ -0,0 +1,159 @@
|
||||
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的评估与方案**,其中的结论可能已被后续决策推翻。
|
||||
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../架构总览.md)。
|
||||
|
||||
# Gitee 方案评估
|
||||
|
||||
> 回答:**「Gitee 算不算一个替代方案?」**
|
||||
>
|
||||
> **结论**:算,而且它是唯一一个**官方支持作为 EdgeOne Pages 代码源**的国内平台。
|
||||
> 但有一道硬门槛 —— **Gitee 免费版单仓库上限 500MB,你的 `.git` 实测 588MB,超了 17.6%**。
|
||||
> 好消息是:**这道门槛跨得过去**(见第四节)。真正要权衡的是另一件事 —— **内容审查**。
|
||||
|
||||
---
|
||||
|
||||
## 一、实测数据(刚量的,不是估算)
|
||||
|
||||
| 指标 | 实测值 |
|
||||
|---|---|
|
||||
| `.git` 总体积 | **588 MB** |
|
||||
| `git count-objects` size-pack | **580 MB**(对象净体积,说明已经打包过了) |
|
||||
| 提交总数 | 955 |
|
||||
| **HEAD 中被跟踪文件合计** | **372.9 MB / 2427 个文件** |
|
||||
| HEAD 中 >1MB 的文件 | 65 个,合计 143.9 MB |
|
||||
|
||||
**关键推论**:`580MB(pack) − 373MB(HEAD) ≈ 207MB` 是**历史里的旧版本 / 已删除对象**。
|
||||
也就是说,**光留当前状态只需要 373MB** —— 这一条决定了瘦身可行。
|
||||
|
||||
---
|
||||
|
||||
## 二、四条硬指标逐项核对
|
||||
|
||||
Gitee 官方配额(help.gitee.com/account/usage-quota):
|
||||
|
||||
| Gitee 免费版限制 | 官方值 | 你的情况 | 判定 |
|
||||
|---|---|---|---|
|
||||
| 单仓库容量 | **≤ 500 MB** | 588 MB | ❌ **超限 17.6%** |
|
||||
| 单文件大小 | ≤ 50 MB | 最大 12.8 MB(mp4) | ✅ 安全 |
|
||||
| 用户总仓库容量 | 5 GB | 588 MB(瘦身后 373 MB) | ✅ 安全 |
|
||||
| 私有仓库协作人数 | 5 人 | 个人 | ✅ 无关 |
|
||||
| 仓库数量 | 1000 个 | 1 个 | ✅ 无关 |
|
||||
|
||||
**只有一条不过:仓库体积。** 而且它刚好卡在一条"能解"的线上。
|
||||
|
||||
---
|
||||
|
||||
## 三、一个被大多数人算错的点:Gitee 方案**不消耗** Gitee Go 的额度
|
||||
|
||||
Gitee Go 免费额度很小(单仓库 200 分钟永久 + 每月 500 分钟)。**但这跟你的方案无关** ——
|
||||
|
||||
因为你走的是 **EdgeOne Pages 的 Git 集成**:代码放 Gitee,**构建跑在 EdgeOne 侧**(4 核 6GB,500 次/月)。
|
||||
Gitee 在这里**只当代码网盘**,一次构建都不消耗它的 CI 分钟。
|
||||
|
||||
> ⚠️ 同理:**不要用 Gitee Pages**。它的构建能力和额度都远不如 EdgeOne,
|
||||
> 而且 2022 年那次全站审查的触发点之一就是 Pages。
|
||||
|
||||
---
|
||||
|
||||
## 四、唯一的硬伤与解法:588MB → 500MB 以下
|
||||
|
||||
`.git` 588MB,其中 **207MB 是历史垃圾**(旧版本 + 已删除文件)。三种解法:
|
||||
|
||||
### 方案 A:只保留当前状态(最彻底,推荐)
|
||||
重建一个只有 HEAD 的仓库 → `.git` 降到 **≈ 373MB**,**留 25% 余量**。
|
||||
|
||||
代价:**955 个提交历史会丢**。
|
||||
但这在你这儿几乎无损失 —— 历史仍在自建 Gitea 那边完整保留,Gitee 只当"构建用的镜像"。
|
||||
|
||||
```bash
|
||||
# 思路(务必先在副本上试,不要直接动主仓库)
|
||||
git checkout --orphan clean-tmp
|
||||
git add -A && git commit -m "squash: 当前站点状态"
|
||||
git branch -D main && git branch -m main
|
||||
git reflog expire --expire=now --all && git gc --prune=now
|
||||
```
|
||||
|
||||
### 方案 B:保留历史,只清理历史中的大文件
|
||||
`git filter-repo --analyze` 先定位占空间的历史大文件,再针对性剔除。
|
||||
体积介于 373–580MB 之间,**需要实测才知道能不能压到 500MB 以下**,不保证成功。
|
||||
|
||||
### 方案 C:升级 Gitee 付费版
|
||||
标准版单仓库 ≤ 1GB,1298 元/年起 —— **为了一个博客每年花 1300,不值得**。
|
||||
|
||||
**结论:只有方案 A 是确定可行的,而且可接受。**
|
||||
|
||||
---
|
||||
|
||||
## 五、真正要权衡的:内容审查(这条比 500MB 更重要)
|
||||
|
||||
Gitee 不是中立的文件存储,它有**实名认证 + 内容审查体系**。有实锤的历史:
|
||||
|
||||
- **2022-05-19,Gitee 把全部约 1000 万个公开仓库临时私有化,做强制审核**,合规的才恢复。
|
||||
开发者必须逐个提交申请、人工复核。有用户 24 个仓库里被恢复了 22 个。
|
||||
- 审查范围包括仓库名、注释、变量名 —— 有开发者抱怨"写代码时还要想这个词会不会触发敏感词列表"。
|
||||
- 常见封号原因:仓库含违规内容(赌博/诈骗/侵权/涉政)、批量建仓被判滥用、开 Pages 发不合规内容。
|
||||
- Gitee 数据全部境内存储,实名是硬要求(这是它拿政府/信创订单的前提)。
|
||||
|
||||
### 但落到你身上,风险评估是**低**的
|
||||
|
||||
理由三条:
|
||||
|
||||
1. **你的内容是技术博客** —— Android 模块化魔改、K3s、Docker、自建服务。这类内容不在敏感区间。
|
||||
2. **把仓库设为私有**。审查压力的大头在**公开仓库**上(2022 那次动的就是公开仓库)。
|
||||
你要用 EdgeOne 构建,私有仓库完全可以(授权访问即可)。
|
||||
3. **国内平台在"政策风险"上对你反而是加分项** —— 你 GitHub 账号被标记,
|
||||
正说明境外平台对你有不确定性。Gitee/CNB 的规则是**明确、可预期**的:
|
||||
别传违禁内容就不会出事,而不是"不知道哪天被风控"。
|
||||
|
||||
---
|
||||
|
||||
## 六、三个国内/境外代码源横向对比
|
||||
|
||||
| | **Gitee** | **CNB(cnb.cool)** | GitLab.com |
|
||||
|---|---|---|---|
|
||||
| 仓库容量 | 500 MB ⚠️ **需瘦身** | **100 GiB** ✅ 不用动 | 2 GB ✅ |
|
||||
| EdgeOne Pages 官方支持 | ✅ 明确支持 | ✅(有官方插件文档) | ✅ 明确支持 |
|
||||
| 构建额度消耗 | 不消耗(构建在 EO 侧) | 不消耗 / 或用它自己的 160 核时 | 不消耗 |
|
||||
| 登录 | 实名注册 | 微信扫码 | 邮箱 |
|
||||
| 国内推送速度 | 快 | 快 | 跨境,588MB 首次推送慢 |
|
||||
| 内容审查 | ⚠️ 有实锤事件 | ⚠️ 官方明写"平台级内容安全审查" | 无(但美国平台) |
|
||||
| 政策风险 | 低(国内合规) | 低 | ⚠️ **与 GitHub 同源风险** |
|
||||
| 与 EdgeOne 的距离 | 第三方 | **同为腾讯体系** | 第三方 |
|
||||
|
||||
### 排序建议
|
||||
|
||||
1. **CNB** —— 100GiB 不用瘦身,零改造,和 EdgeOne 同属腾讯、有官方集成文档
|
||||
2. **Gitee** —— 官方支持、国内快,但**要先做一次历史瘦身**(一次性工作,可接受)
|
||||
3. **GitLab.com** —— 容量够,但**美国平台,和 GitHub 同类风险**,且首次推送跨境 588MB 很慢
|
||||
|
||||
**Gitee 输给 CNB 的唯一一点就是那 500MB**,如果你不想动仓库历史,选 CNB;
|
||||
如果你更信任 Gitee 这个老牌子、也愿意做一次瘦身,Gitee 完全可用。
|
||||
|
||||
---
|
||||
|
||||
## 七、Gitee 方案的完整形态
|
||||
|
||||
```
|
||||
write-server / 本地 hugo → push Gitee(私有仓库)
|
||||
→ EdgeOne Pages Git 集成自动构建(4核6G,500 次/月,不消耗 Gitee CI 额度)
|
||||
→ EdgeOne 国际站(境外解析) + EdgeOne 国内站 Makers(境内解析,绑备案域名)
|
||||
```
|
||||
|
||||
砍掉:act_runner、广州中转机、sync.sh、COS、Gitea artifact 链、8 处 Gitea 兼容分支、
|
||||
又拍云、多吉云、两套冗余通知。
|
||||
**3 台机器 → 0 台;7 环节 → 3 环节。**
|
||||
|
||||
---
|
||||
|
||||
## 八、前置动作(按顺序)
|
||||
|
||||
1. **先备份**:整仓 `cp -r` 一份(或 `git bundle create` 全量)
|
||||
2. **在副本上做瘦身**,验证 `.git` 能压到 500MB 以下
|
||||
3. 注册 Gitee,建**私有**仓库,首次推送验证体积
|
||||
4. 在 EdgeOne Pages 里接 Gitee 仓库,跑一次构建
|
||||
5. 确认无误后,才把主仓 remote 切过去
|
||||
|
||||
**第 1、2 步不做,其余都别动。**
|
||||
|
||||
---
|
||||
|
||||
*本文档基于 2026-10-04 实测数据与官方文档。仓库体积为 `git count-objects -vH` 实测,非估算。*
|
||||
@@ -0,0 +1,202 @@
|
||||
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的评估与方案**,其中的结论可能已被后续决策推翻。
|
||||
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../架构总览.md)。
|
||||
|
||||
# 代码源与构建平台选型
|
||||
|
||||
> 回答的问题:**「想简化是不是只能走 EdgeOne?」**
|
||||
>
|
||||
> **结论先行**:不是"只能",但在你当前的约束下,**EdgeOne 是最省事的那一个**。
|
||||
> 而且真正要换的不是 CDN —— 是**「托管构建」**。EdgeOne 恰好一条顶两条(构建 + 分发),
|
||||
> 这是 Cloudflare 和阿里云 ESA 都做不到的。
|
||||
>
|
||||
> 另外有一个**会改变结论的数字**:Gitee 免费版单仓库上限 **500MB**,而你的 `.git` 是 **588MB**。
|
||||
> 所以国内代码源的第一选择不是 Gitee,而是 **CNB**。
|
||||
|
||||
---
|
||||
|
||||
## 一、把问题重新定义一次
|
||||
|
||||
你说「之前是 GitHub Actions 部署,用得很稳,但账号被标记了」。
|
||||
|
||||
那么现在这一整套东西,本质是**你自己复刻了一套 GitHub Actions**:
|
||||
|
||||
| GitHub Actions 原来的角色 | 你现在用自建件替代 |
|
||||
|---|---|
|
||||
| github.com(代码托管) | 自建 Gitea |
|
||||
| GitHub 的 runner(构建执行) | act_runner |
|
||||
| `upload-artifact`(产物传递) | Gitea artifact → COS → 中转机 |
|
||||
| Pages 直连(产物落地) | sync.sh → 又拍云 → 多吉云 |
|
||||
|
||||
**所以要"简化回去",正确的问题是:找一个托管的构建服务,把这四个自建件一起替掉。**
|
||||
|
||||
CDN 选谁(EdgeOne / CF / ESA / 多吉云)是**另一个问题**,它不解决构建复杂度。
|
||||
|
||||
---
|
||||
|
||||
## 二、三条硬约束(都核实过,不是印象)
|
||||
|
||||
| 约束 | 实测/官方值 | 影响 |
|
||||
|---|---|---|
|
||||
| 你的仓库体积 | `.git` **588MB** / 955 提交;工作区 803MB | 决定代码源能不能装下 |
|
||||
| 你的产物体积 | `public` 424MB / **3267 文件**,最大单文件 12.8MB | 决定托管平台的文件数/单文件门槛 |
|
||||
| Hugo 版本 | 0.128.2 | 托管构建需能指定版本 |
|
||||
| 备案 | **鄂ICP备2022015735号-1** | 境内加速的前提,你**已具备** |
|
||||
|
||||
---
|
||||
|
||||
## 三、★ 三个关键发现
|
||||
|
||||
### 发现 1:EdgeOne Pages **官方支持 Gitee / GitLab 作为 Git 源**
|
||||
|
||||
官方文档原文:*「Pages 目前支持 GitHub, GitLab, Gitee 等 Git 提供商的接入」*。
|
||||
第三方 Nitro 部署文档也写:*「EdgeOne supports deployments from GitHub, GitLab, Gitee, and CNB」*。
|
||||
|
||||
**这条直接决定了「能不能找回 GitHub Actions 那种简单感」—— 能。**
|
||||
代码推到国内托管平台 → EdgeOne 自动拉取、自动构建、自动部署。**不需要你自己的 runner。**
|
||||
|
||||
### 发现 2:Gitee 免费版装不下你的仓库
|
||||
|
||||
Gitee 官方配额页(help.gitee.com/account/usage-quota):
|
||||
|
||||
| 项 | 社区版免费额度 |
|
||||
|---|---|
|
||||
| 单仓库容量 | **≤ 500 MB** |
|
||||
| 单文件 | ≤ 50 MB |
|
||||
| 用户总仓库容量 | 5 GB |
|
||||
|
||||
**你的 `.git` 是 588MB → 超了 17.6%。** 推上去会被锁定推拉服务。
|
||||
(Gitee 提供 `git-repo-clean` 瘦身工具可以降到 500MB 以下,但那是额外工作。)
|
||||
|
||||
### 发现 3:CNB 是更合适的国内代码源 —— 而且和 EdgeOne 有官方集成
|
||||
|
||||
**CNB(Cloud Native Build,cnb.cool)** 是腾讯的 AI Native Git 平台,社区版免费:
|
||||
|
||||
| 项 | 免费额度 |
|
||||
|---|---|
|
||||
| 仓库存储 | **100 GiB**(你的 588MB 毫无压力) |
|
||||
| 对象存储 | 100 GiB |
|
||||
| 云原生构建 | **160 核时/月** |
|
||||
| 云原生开发 | 1600 核时/月 |
|
||||
| 登录方式 | 微信扫码 |
|
||||
|
||||
**160 核时换算**:4 核跑 10 分钟 = 4 × (10/60) ≈ 0.67 核时 → 一个月能跑 **约 240 次构建**。你今天按每月 60–90 次算,**用掉不到 40%**。
|
||||
|
||||
而且 EdgeOne 官方专门写了 **CNB 插件文档**(`pages.edgeone.ai/document/using-cnb-plugin`):
|
||||
> 在 CNB 流水线里 `npm run build` → `npx edgeone pages deploy -n <项目名> -t $EDGEONE_API_TOKEN`
|
||||
|
||||
**这条路官方背书,100% 可行。**
|
||||
|
||||
---
|
||||
|
||||
## 四、四种组合对比
|
||||
|
||||
| | 代码源 | 构建在哪 | 产物去向 | 自维护机器 | 免费额度 | 卡点 |
|
||||
|---|---|---|---|---|---|---|
|
||||
| **① CNB + EdgeOne Pages** ★ | CNB | **CNB 流水线**(托管) | EdgeOne 国际 + 国内 | **0 台** | 100GiB + 160 核时/月 + 500 构建/月 | 需绑微信/腾讯云账号 |
|
||||
| ② Gitee + EdgeOne Pages | Gitee | EdgeOne Git 集成(4核6G) | EdgeOne 国际 + 国内 | **0 台** | 5GB / 500 构建/月 | **仓库必须先瘦身到 500MB 以下** |
|
||||
| ③ GitLab.com + CF Pages | GitLab.com | CF 侧 | **仅 CF**(产物拿不出来) | 0 台 | CF 500 次/月 | 境内无解;CF 国内访问慢 3 倍 |
|
||||
| ④ 保留 Gitea + EdgeOne Pages | 自建 Gitea(mirror→CNB) | CNB | EdgeOne | **1 台**(Gitea) | 同 ① | 没砍干净;但写作后台零改动 |
|
||||
|
||||
**为什么推荐 ①**:唯一一个同时满足「代码源在国内且装得下仓库」+「构建托管」+「境内外都能落」+「免费」的组合。
|
||||
|
||||
---
|
||||
|
||||
## 五、推荐形态
|
||||
|
||||
```
|
||||
写作侧 构建(托管) 分发(托管)
|
||||
┌────────────────────┐ ┌──────────────────────────┐ ┌──────────────────────────┐
|
||||
│ write-server │ │ CNB(cnb.cool) │ │ EdgeOne 国际站 Pages │
|
||||
│ (本地/服务器) │ push │ 免费 100GiB / 160 核时/月 │ │ → usj.cc 境外解析 │
|
||||
│ 直接写 .md + git ├─────────▶│ │ │ │
|
||||
│ 只改 remote URL │ │ .cnb.yml: │──▶│ EdgeOne 国内站 Makers │
|
||||
└────────────────────┘ │ hugo --minify │ │ → 备案域名 境内解析 │
|
||||
│ edgeone pages deploy │ │ │
|
||||
或本地 hugo 后手动 push ─────▶│ (境外 + 境内 两个项目)│ └──────────────────────────┘
|
||||
└──────────────────────────┘
|
||||
```
|
||||
|
||||
### `.cnb.yml` 骨架(复刻你现在 deploy.yml 做的事)
|
||||
|
||||
```yaml
|
||||
main:
|
||||
push:
|
||||
stages:
|
||||
- name: 构建 Hugo 站点
|
||||
image: klakegg/hugo:0.128.2-ext
|
||||
script: |
|
||||
hugo --minify --gc
|
||||
|
||||
- name: 部署境外
|
||||
image: node:20
|
||||
script: |
|
||||
npx edgeone pages deploy ./public \
|
||||
-n hugo-blog-overseas -t $EDGEONE_TOKEN_INTL -a overseas
|
||||
|
||||
- name: 部署境内
|
||||
image: node:20
|
||||
script: |
|
||||
npx edgeone pages deploy ./public \
|
||||
-n hugo-blog-cn -t $EDGEONE_TOKEN_CN -a global
|
||||
```
|
||||
|
||||
> ⚠️ `-a global`(含中国大陆)目前只在**国际站**文档里明确,且官方文档自相矛盾。
|
||||
> 另一条稳妥路径是**国内站 Makers 单独建一个项目**(账号体系与国际站独立),
|
||||
> 绑你的备案域名。这个需要实测一次定论。
|
||||
|
||||
---
|
||||
|
||||
## 六、砍掉 / 保留
|
||||
|
||||
### 砍掉(9 项)
|
||||
|
||||
| 砍掉 | 原因 |
|
||||
|---|---|
|
||||
| act_runner | CNB 托管构建取代 |
|
||||
| 广州中转机 | 产物直接落在 EdgeOne,不需要中转 |
|
||||
| `sync.sh` 轮询 | 同上 |
|
||||
| 腾讯云 COS | 同上(砍 COS 这件事本身也随之结束) |
|
||||
| Gitea artifact 链 | 那串 `v3/v4` 兼容坑一起消失 |
|
||||
| 8 处 `github.server_url` 兼容分支 | 不再需要伪装成 GitHub |
|
||||
| 又拍云 | EdgeOne 国内站直接 serve 境内 |
|
||||
| 多吉云 | 同上(境内 CDN 层) |
|
||||
| 三套通知里的两套 | 保留一套即可 |
|
||||
|
||||
**发布链路:7 环节 → 3 环节**(写作 → 构建 → 上线)
|
||||
**自维护机器:3 台 → 0 台**
|
||||
**厂商:Gitea自建 + COS + 又拍云 + 多吉云 + EdgeOne + 失效的 GitHub → CNB + EdgeOne(同为腾讯体系)**
|
||||
|
||||
### 保留
|
||||
|
||||
- **Hugo + content + themes** —— 完全不动
|
||||
- **blog-admin(artalk-cf)** —— 本来就跑在 CF Workers,一行不改
|
||||
- **write-server** —— **几乎不用改**,只把 `origin` 的 remote URL 指向 CNB。
|
||||
CNB 是标准 git + 提供统一 HTTPS Token,`lib/git.ts` 的 `git pull --rebase` / `git push` 逻辑照常工作
|
||||
|
||||
---
|
||||
|
||||
## 七、待确认(3 条,按重要性排序)
|
||||
|
||||
1. **EdgeOne 免费版的流量额度**。官方「限制与配额」页**没有列「流量」这一项**;第三方说法互相矛盾(一处说 50GB/月,一处说不限量)。
|
||||
按你的站点规模估算:单页 1–3MB,50GB/月 ≈ 2–5 万次浏览 —— 个人博客大概率够,
|
||||
但**那个 12.8MB 的 mp4 如果被反复播放会吃掉不少**。这一条开工前必须先确认。
|
||||
2. **CNB 是否可直接作为 EdgeOne Pages 的 Git 源导入**。第三方文档说支持,官方只在插件路径里明确。
|
||||
不影响可行性(走插件路径必然可行),只影响配置方式。
|
||||
3. **境内用国际站 `-a global` 还是国内站 Makers 独立项目**。一次实验可定论。
|
||||
|
||||
---
|
||||
|
||||
## 八、最小验证(成本极低,建议先做)
|
||||
|
||||
不用改任何现有东西,**一次性验证整条链路是否成立**:
|
||||
|
||||
1. 建一个 CNB 仓库(微信扫码,2 分钟)
|
||||
2. 往里放一个最小 Hugo 站 + 上面的 `.cnb.yml`(或先放个 hello world)
|
||||
3. 拿一个 EdgeOne API Token(你已经有),跑一次 push
|
||||
4. 看三件事:**CNB 能不能构建** → **能不能部署到 EdgeOne** → **国内机实测访问延迟**
|
||||
|
||||
这一步跑通,等于确认了整条路;跑不通,损失是 20 分钟,不是 30 天。
|
||||
|
||||
---
|
||||
|
||||
*本文档基于 2026-10-04 核实的官方文档与实测数据。所有配额均引自官方页面,第三方来源已标注。*
|
||||
@@ -0,0 +1,219 @@
|
||||
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的评估与方案**,其中的结论可能已被后续决策推翻。
|
||||
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../架构总览.md)。
|
||||
|
||||
# 砍掉腾讯云 COS 中转层 —— 完整改造步骤
|
||||
|
||||
> 目标:把「build → COS → 中转机 → 又拍云 → 多吉云」这条绕路,
|
||||
> 改成「build → Gitea artifact →(中转机拉取)→ 又拍云 → 多吉云」,
|
||||
> 砍掉腾讯云 COS 这一层,省下 COS 存储/流量账单。
|
||||
|
||||
> 状态(2026-10-04 更新):
|
||||
> - ✅ `deploy.yml` 已改完并**已推送**
|
||||
> - ✅ 中转机 `sync.sh.new`(artifact 版)已上传到 `/opt/upyun-sync/sync.sh.new`,**尚未生效**
|
||||
> - ✅ Gitea 只读 token 已写入中转机 `/opt/upyun-sync/.gitea_token`(600 root:root)
|
||||
> - ❌ 链路**尚未跑通**:run #55 倒在 v4 不支持,run #56 倒在 v3 的 finalize 500
|
||||
> - ⏸️ 最新修复(单文件 tar,commit `1f568bbf`)**本地已提交、待推送**
|
||||
> - ⚠️ `deploy.yml` 与 `sync.sh` 必须一起生效,否则国内线路停更(见下)
|
||||
|
||||
---
|
||||
|
||||
## 零、实测踩到的两个坑(都已修,记录备用)
|
||||
|
||||
### 坑 1:`upload-artifact@v4` 在 Gitea 上直接失败(run #55)
|
||||
|
||||
```
|
||||
::error::@actions/artifact v2.0.0+, upload-artifact@v4+ and download-artifact@v4+
|
||||
are not currently supported on GHES.
|
||||
```
|
||||
|
||||
Gitea 被 v4 识别为 GHES,但它没实现新版 artifact API → **降级 v3**(commit `ed38f938`)。
|
||||
|
||||
### 坑 2:v3 传「目录」时 Gitea finalize 返回 500(run #56,耗时 30 分钟)
|
||||
|
||||
v3 收目录是**逐文件上传**:3216 个 blob / 376MB 全部传完(日志可见 `Processed file #3216`),
|
||||
但最后的 finalize 调用被 Gitea 拒绝:
|
||||
|
||||
```
|
||||
Finalize artifact upload - Attempt 1..5 of 5 failed with error: Request timeout
|
||||
::error::Finalize artifact upload failed: Artifact service responded with 500
|
||||
```
|
||||
|
||||
**结论:Gitea 扛不住「文件数多」的 artifact。** 改法(commit `1f568bbf`):
|
||||
build 侧先把 `public/` 打成**单个** `public.tar.zst`,只上传这 1 个文件。
|
||||
副作用是好的——产物结构从此完全确定,不再有「解出来会不会多一层 `public/`」的歧义。
|
||||
|
||||
---
|
||||
|
||||
## 一、为什么不能只推一半(重要)
|
||||
|
||||
deploy.yml 改完后,build 产物**不再上传 COS**,只进 Gitea artifact。
|
||||
而国内中转机的 sync.sh 如果**还从 COS 拉**,就会:
|
||||
|
||||
- build 传 artifact → COS 没有新产物
|
||||
- 中转机从 COS 拉 → 拿到的是旧产物 / 拉不到
|
||||
- **国内线路(又拍云 + 多吉云)停更**
|
||||
|
||||
所以 `deploy.yml` 和 `sync.sh` 必须**同步改、同步推**,不能只推 deploy.yml。
|
||||
|
||||
---
|
||||
|
||||
## 二、已完成的改动(deploy.yml)
|
||||
|
||||
文件:`.github/workflows/deploy.yml`
|
||||
|
||||
### build job
|
||||
- ❌ 删掉:「Setup Python」「Install/Configure coscmd」「Get last build hash from COS」「Check if upload is needed」「Upload to Tencent COS」「Upload hash to COS」
|
||||
- ✅ 新增:「Upload build artifact (public/)」→ `actions/upload-artifact@v4`,name=`hugo-public`,path=`public/`,retention-days=7
|
||||
- 保留:「Report deploy status (built)」上报 hash 到 `api.200181.xyz`
|
||||
|
||||
### deploy-edgeone job
|
||||
- ❌ 删掉:「Check if deployment is needed」(last_hash 判断)、「Setup Python」「Install/Configure coscmd」「Download files from COS」
|
||||
- ✅ 改成:`actions/download-artifact@v4`(name=`hugo-public`,path=`public/`)→ 直接 `npx edgeone pages deploy ./public`
|
||||
- `deployed` 恒为 true(push 才触发,本就该部署)
|
||||
|
||||
### 清理
|
||||
- 删掉所有 `download_duration` / `last_hash` / `need_upload` / `coscmd` 引用(通知、表格里的「下载 COS」等)
|
||||
|
||||
---
|
||||
|
||||
## 三、剩下的改动:sync.sh(国内中转机)
|
||||
|
||||
文件:`/opt/upyun-sync/sync.sh`(国内机 119.29.215.187,通过 1Panel API 或 SSH 操作)
|
||||
|
||||
### 要改的核心逻辑
|
||||
|
||||
原流程(第 1-3 步):
|
||||
```bash
|
||||
# 1. 取远端 hash:从 COS 读 /__build_hash(cos_sign.py 签名)
|
||||
# 2. 比对本地 hash,无变化退出
|
||||
# 3. 从 COS 下载 public.tar.zst
|
||||
```
|
||||
|
||||
新流程:
|
||||
```bash
|
||||
# 1. 调 Gitea API 列出最新 artifact
|
||||
# GET https://gitea.usj.cc/api/v1/repos/zqlit/blog/actions/artifacts?name=hugo-public
|
||||
# (Header: Authorization: token <GITEA_TOKEN>)
|
||||
# 2. 拿最新一个 artifact 的 id,下载 zip
|
||||
# GET .../actions/artifacts/{id}/zip (302 重定向,curl -L 跟随)
|
||||
# 3. 解压 zip → 读 public/.build_hash → 比对本地 hash
|
||||
# 有变化才继续走「upx sync 又拍云 → purge → 刷多吉云」
|
||||
```
|
||||
|
||||
### 需要的准备
|
||||
|
||||
1. **Gitea 只读 token**:
|
||||
- Gitea 后台(gitea.usj.cc)→ 头像 → 设置 → 应用 → 生成令牌
|
||||
- 名称随意(如 `upyun-sync`),勾选 `read:repository` 即可(只读够用)
|
||||
- 生成后把 token 存到中转机 `/opt/upyun-sync/.gitea_token`(chmod 600)
|
||||
|
||||
2. 中转机访问 Gitea 的网络:已实测 0.56s,稳定,无问题。
|
||||
|
||||
### sync.sh 改动示例(第 1-3 步替换成如下)
|
||||
|
||||
```bash
|
||||
# ---------- 取最新构建(从 Gitea artifact,替代原 COS)----------
|
||||
GITEA="https://gitea.usj.cc"
|
||||
REPO="zqlit/blog"
|
||||
TOKEN=$(cat "$ROOT/.gitea_token" 2>/dev/null)
|
||||
|
||||
# 1. 列出 hugo-public artifact,拿最新 id + created_at
|
||||
ART_LIST=$(curl -fsS --max-time 40 -H "Authorization: token $TOKEN" \
|
||||
"$GITEA/api/v1/repos/$REPO/actions/artifacts?name=hugo-public" 2>/dev/null)
|
||||
ART_ID=$(echo "$ART_LIST" | python3 -c "import sys,json; a=json.load(sys.stdin); print(a[-1]['id'] if a else '')")
|
||||
|
||||
[ -n "$ART_ID" ] || { say "❌ 没有找到 hugo-public artifact"; exit 1; }
|
||||
|
||||
# 2. 下载 artifact zip
|
||||
rm -f "$ROOT/artifact.zip"
|
||||
curl -fSL --max-time 600 -H "Authorization: token $TOKEN" \
|
||||
"$GITEA/api/v1/repos/$REPO/actions/artifacts/$ART_ID/zip" \
|
||||
-o "$ROOT/artifact.zip" || { say "❌ 下载 artifact 失败"; exit 1; }
|
||||
|
||||
# 3. 解压(artifact zip 里是 public/ 的内容)
|
||||
rm -rf "$ROOT/public.new"; mkdir -p "$ROOT/public.new"
|
||||
unzip -q "$ROOT/artifact.zip" -d "$ROOT/public.new" || { say "❌ 解压失败"; exit 1; }
|
||||
|
||||
# 4. 读 hash 比对(.build_hash 在 zip 里 public/.build_hash)
|
||||
REMOTE=$(cat "$ROOT/public.new/.build_hash" 2>/dev/null | tr -d ' \r\n')
|
||||
LOCAL=$(cat "$STAMP" 2>/dev/null | tr -d ' \r\n')
|
||||
if [ "$REMOTE" = "$LOCAL" ] && [ -f "$PUBLIC/index.html" ]; then
|
||||
say "无变化 ${REMOTE:0:12}…"; exit 0
|
||||
fi
|
||||
say "发现新构建: ${LOCAL:0:12}… -> ${REMOTE:0:12}…"
|
||||
|
||||
# 后续:原子切换 public.new → public,然后照旧 upx sync / purge / 刷多吉云
|
||||
# (这部分逻辑不变,只是"下载产物"和"取 hash"的来源从 COS 换成了 artifact)
|
||||
```
|
||||
|
||||
> ⚠️ 注意:artifact 解压出来的目录结构取决于 `upload-artifact` 的 path。
|
||||
> deploy.yml 里 `path: public/`,所以 zip 里是 `public/...`,解压后要取 `public.new/public/`
|
||||
> 或调整 path。实测一次 build 看 zip 结构最稳。
|
||||
|
||||
---
|
||||
|
||||
## 四、执行顺序(照着做)
|
||||
|
||||
### 第 1 步:生成 Gitea token
|
||||
Gitea 后台 → 设置 → 应用 → 生成令牌 → 只读 → 复制 token
|
||||
|
||||
### 第 2 步:token 放到中转机
|
||||
```bash
|
||||
# 通过 1Panel API 或 SSH(国内机)
|
||||
echo "你的token" > /opt/upyun-sync/.gitea_token
|
||||
chmod 600 /opt/upyun-sync/.gitea_token
|
||||
```
|
||||
|
||||
### 第 3 步:改 sync.sh
|
||||
按上面「三」的示例,把「取 hash + 下载」两段从 COS 换成 Gitea artifact。
|
||||
|
||||
### 第 4 步:推 deploy.yml
|
||||
```bash
|
||||
cd /e/GitHub/blog
|
||||
git add .github/workflows/deploy.yml
|
||||
git commit -m "chore: 砍掉 COS 中转,build 产物改用 Gitea artifact 传递"
|
||||
git push gitea main
|
||||
```
|
||||
|
||||
### 第 5 步:验证
|
||||
1. 看 Gitea Actions 这次 build 是否成功(重点看 `upload-artifact` 有没有报错——这是 Gitea 28 兼容性风险点)
|
||||
2. 看中转机 sync.log 有没有「✅ 同步完成」
|
||||
3. 打开 `https://api.200181.xyz/api/deploy-status` 看国内线路是否 synced
|
||||
4. 访问 usj.cc 看国内是否更新
|
||||
|
||||
### 第 6 步:确认稳定后,清理 COS
|
||||
- 删 Gitea secrets 里的 COS_SECRET_ID / COS_SECRET_KEY / COS_BUCKET / COS_REGION(先留着观察几天再删)
|
||||
- 腾讯云 COS 桶 `hugo-1303964578` 可以清空或删桶(确认不再被引用后)
|
||||
- 中转机的 `cos_sign.py` 可以删
|
||||
|
||||
---
|
||||
|
||||
## 五、风险点与回退
|
||||
|
||||
| 风险 | 说明 | 对策 |
|
||||
|---|---|---|
|
||||
| `upload-artifact@v4` 在 Gitea 28 兼容性 | v4 是新版 action,Gitea 兼容层可能只支持 v3 | 若报错,降级到 `actions/upload-artifact@v3` |
|
||||
| artifact 保留期 7 天 | 若长时间不部署,artifact 过期 | retention-days 设大,或确认 deploy-status 兜底 |
|
||||
| zip 目录结构 | `path: public/` 解压后是 `public/...` 还是直接文件 | 实测一次 build 看 zip 结构再定解压路径 |
|
||||
| 回退 | 万一 artifact 链路不通 | 原 deploy.yml 备份在 `.workbuddy-backup/deploy.yml.20261004-085652`,`git revert` 即可回 COS |
|
||||
|
||||
---
|
||||
|
||||
## 六、原始备份位置
|
||||
|
||||
- deploy.yml 原始版本:`E:/GitHub/blog/.workbuddy-backup/deploy.yml.20261004-085652`
|
||||
- 已改版本:`E:/GitHub/blog/.github/workflows/deploy.yml`(未推送)
|
||||
|
||||
---
|
||||
|
||||
## 七、关键信息速查
|
||||
|
||||
| 项 | 值 |
|
||||
|---|---|
|
||||
| 境外 Gitea | `23.254.236.47:3001`(域名 gitea.usj.cc),SSH root / `***REMOVED-ROOT-PW***` |
|
||||
| Gitea 数据 | docker `gitea/gitea:latest`,`/opt/gitea/data`,SQLite |
|
||||
| 国内中转机 | `119.29.215.187:3721`(1Panel),又拍云同步任务 ID=15 |
|
||||
| 中转机 sync.sh | `/opt/upyun-sync/sync.sh` |
|
||||
| Gitea artifact API | `GET /api/v1/repos/zqlit/blog/actions/artifacts` 和 `/{id}/zip` |
|
||||
| 又拍云 | bucket=`imzql`,operator=`1770186415` |
|
||||
| 多吉云 | AK=`4fa23701981899fb`(sync.sh 内已硬编码) |
|
||||
@@ -0,0 +1,231 @@
|
||||
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的评估与方案**,其中的结论可能已被后续决策推翻。
|
||||
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../架构总览.md)。
|
||||
|
||||
# 精简方案:只留 Cloudflare + Hugo
|
||||
|
||||
> 2026-10-04
|
||||
> 目标:砍掉全部自建基础设施,只保留 **Hugo**(构建)和 **Cloudflare**(一切服务端)。
|
||||
> 文中所有平台限制均来自官方文档核实,非推测。
|
||||
|
||||
---
|
||||
|
||||
## 一、决定一切的硬约束
|
||||
|
||||
**Cloudflare 唯一不能替你做的是「代码托管」。** 它的两条部署路线直接决定架构形态:
|
||||
|
||||
| 模式 | 代码源 | 构建在哪 | 适用场景 |
|
||||
|---|---|---|---|
|
||||
| **Git 集成** | **只认 github.com / gitlab.com**<br>(官方原文:*does not currently support connecting self-hosted instances*) | Cloudflare 侧自动构建 | 要「push 即上线」 |
|
||||
| **Direct Upload** | 不需要 git | 不构建,你本地构建好推产物 | 要「零第三方依赖」 |
|
||||
|
||||
> ⚠️ **两种模式在项目创建时定死,事后不能互转**(官方明说)。选错只能重建项目 —— 这是最容易踩的坑。
|
||||
> 变通办法:建 **Git 集成**项目,之后在 `Settings → Builds` 关掉「自动部署」,再用 `wrangler` 直传 —— 这样两种方式都能用(**反过来不行**)。
|
||||
|
||||
### 关键结论
|
||||
|
||||
**GitHub 被封 ≠ 必须自建 Gitea。** 你不需要「自建 git 托管」这种复杂度,只需要回答一个问题:
|
||||
|
||||
> **你要不要「不开电脑也能发文」?**
|
||||
|
||||
---
|
||||
|
||||
## 二、两条路线
|
||||
|
||||
### 形态 A · 本地构建直传(最简,零第三方)
|
||||
|
||||
```
|
||||
你的电脑 Cloudflare
|
||||
┌─────────────────────┐ ┌──────────────┐
|
||||
│ 写 md → hugo build │──wrangler─▶│ Pages (静态站) │
|
||||
└─────────────────────┘ pages ├──────────────┤
|
||||
deploy │ Workers (评论/RSS) │
|
||||
└──────────────┘
|
||||
```
|
||||
|
||||
- **组件数**:1 台自己的电脑 + Cloudflare
|
||||
- **第三方依赖**:0(连 git 托管都不要)
|
||||
- **发布链路**:3 步,全在本机
|
||||
- 代码备份:本地仓库即可,要冗余可推任意 git,或存 CF R2
|
||||
- **代价**:发文必须开电脑
|
||||
|
||||
### 形态 B · GitLab.com 当代码源 + CF 自动构建
|
||||
|
||||
```
|
||||
写 md ──push──▶ gitlab.com ──自动构建──▶ Cloudflare Pages ──▶ 上线
|
||||
Cloudflare Workers (评论/RSS)
|
||||
```
|
||||
|
||||
- **组件数**:gitlab.com + Cloudflare
|
||||
- **★ 关键**:构建跑在 **Cloudflare 侧**(免费 500 次/月、单次 20 分钟超时),**不消耗 GitLab 的 400 分钟**
|
||||
→ 所以之前担心的「GitLab 免费版 400 分钟/月不够用」在这套组合下**根本不成立**
|
||||
- 额度核对:本站 3267 文件 / 最大单文件 12.8MB → CF 上限 20,000 文件 / 25MiB ✅ 完全够
|
||||
- **代价**:多一个外部账号
|
||||
|
||||
---
|
||||
|
||||
## 三、可以整个删掉的(9 项)
|
||||
|
||||
| # | 删掉的 | 原本的作用 |
|
||||
|---|---|---|
|
||||
| 1 | **Gitea** | 自建 git 托管(GitHub 被封后的替代品) |
|
||||
| 2 | **act_runner** | 自建 CI runner |
|
||||
| 3 | **广州中转机 + `sync.sh`** | 每分钟轮询、把产物搬去又拍云 |
|
||||
| 4 | **又拍云** | 国内源站 |
|
||||
| 5 | **多吉云** | 国内 CDN,回源又拍云 |
|
||||
| 6 | **EdgeOne Pages** | 境外线路托管 |
|
||||
| 7 | **腾讯云 COS** | 境外产物 → 国内的中转层 |
|
||||
| 8 | **artifact 传递链** | 跨 job 传 424MB(含 v3/v4 那串坑) |
|
||||
| 9 | **兼容分支与冗余通知** | `github.server_url` 判断 ×8、TG/飞书/邮件三套、`if:false` 死代码约 100 行 |
|
||||
|
||||
**发布链路从 7 环节降到 3 环节;需要自己运维的机器从 3 台降到 0 台。**
|
||||
|
||||
---
|
||||
|
||||
## 四、Cloudflare 侧能白捡留下的
|
||||
|
||||
**`blog-admin/`(artalk-cf 评论后端 + RSS 机器人)本来就是 CF Workers + D1 + KV —— 一行都不用改。**
|
||||
|
||||
这是你现有架构里唯一「已经完全符合目标形态」的部分:
|
||||
- 评论系统 → `api.200181.xyz`,照常
|
||||
- RSS 订阅抓取、友链朋友圈数据 → 照常
|
||||
- 后台管理(`/admin/` 与 `/sidebar/`)→ 照常
|
||||
|
||||
**换句话说:你的「后端」其实早就已经是 Cloudflare 了,复杂的只是「发布管线」。**
|
||||
|
||||
---
|
||||
|
||||
## 五、必须接受的代价(诚实说)
|
||||
|
||||
### 1. 国内访问会变慢 ← 最大的一笔
|
||||
|
||||
Cloudflare 免费版在中国大陆走**境外节点**(没有 ICP 备案就用不了大陆节点,China Network 要企业版)。
|
||||
现在这套「又拍云 + 多吉云」的存在意义**就是为了这个**。
|
||||
|
||||
**2026-10-04 国内机实测**(腾讯云广州,见「五·补」章):CF 首字节 **0.61–0.89s**,
|
||||
而现在的国内 CDN 是 **0.18–0.32s** —— 即 **CF 比国内 CDN 慢约 2–4 倍**。
|
||||
能开、不算快,对个人博客通常可接受,但你要心里有数。
|
||||
|
||||
### 2. 写作后台(`post.usj.cc`)会没有
|
||||
|
||||
那套 Next.js 直接读写本地 `.md` 文件、依赖文件系统,**CF 上跑不了**。要么:
|
||||
- 重写成 CF Worker(内容改存 R2/D1,图片存 R2)—— 你会写 Worker,技术可行,但是工作量
|
||||
- 退回本地写作(配合形态 A 正好)
|
||||
|
||||
### 3. Telegram bot 发文、公众号发布会断
|
||||
|
||||
同理,需要重写成 CF Worker 才能保留。
|
||||
|
||||
### 4. 构建前的脚本要处理
|
||||
|
||||
`check_links.js`(友链检查)、`generate_circle_data.js`(朋友圈数据)、`add_draft_to_hidden.py` 这些:
|
||||
- 要么塞进 CF Pages 的构建命令里(需要 `npm ci`,会拖慢构建、且 CF 构建环境要能装依赖)
|
||||
- 要么去掉(友情链接检查其实没必要每次构建都做)
|
||||
|
||||
---
|
||||
|
||||
## 五·补、国内访问能不能救?(2026-10-04 国内机实测)
|
||||
|
||||
用国内那台机器(腾讯云广州,`119.29.215.187`)实测,每项 3 次取代表值:
|
||||
|
||||
| 目标 | 首字节 TTFB | 连接建立 | 走哪个节点 |
|
||||
|---|---|---|---|
|
||||
| `usj.cc`(现状:EdgeOne **国内**节点) | **0.18–0.32s** | 0.01–0.04s | 成都 / 浙江 |
|
||||
| `api.200181.xyz`(你自己的 CF Workers) | **0.61–0.89s** | 0.20–0.45s | CF Anycast(IPv6) |
|
||||
| `cravatar.cn`(头像是 CF 的) | 0.65–0.71s | 0.23s | CF Anycast |
|
||||
| `spst2.com`(页首统计脚本) | 0.087s | 0.011s | 有国内节点,**不是问题** |
|
||||
|
||||
**两条硬结论:**
|
||||
|
||||
1. **CF 免费版在国内比国内 CDN 慢约 2–4 倍**(TTFB 0.6–0.9s vs 0.2–0.3s)。
|
||||
2. **实测发现 CF 的连接走了 IPv6**(`2606:4700::…`),握手要 0.20–0.45s;
|
||||
同一时刻 IPv4 握手只要 **0.058s**。→ **IPv6 到 CF 的路由在国内明显更差**,
|
||||
这是一个可以单独利用的抓手。
|
||||
|
||||
### 能加速的三条路
|
||||
|
||||
**路 A · 官方(走不通)**
|
||||
Cloudflare China Network 需要:Enterprise 企业版 + 单独订阅 + **每个主域名持有效 ICP 备案** +
|
||||
京东云内容审核。个人博客没戏。
|
||||
|
||||
**路 B · 社区「优选 IP」(有效,但违反 ToS)**
|
||||
原理:CF 用 Anycast 广播,大陆解析到的 IP 段路由差。做法是**让大陆用户的 DNS 解析结果
|
||||
指向另一段「对大陆友好」的 CF IP**。
|
||||
- 预期效果:按本机实测基线,合理预期是 **0.6s → 0.2–0.3s**(社区常说的「5s→2s」是针对更差的默认线)
|
||||
- ⚠️ **Pages 不能直接改 CNAME**(会返回 `1001`)→ 必须「转成 Worker」或「交给第三方 DNS 分线路解析」
|
||||
- ⚠️ **明文违反 CF 服务条款 2.2.1(b)**:*causing traffic for your Cloudflare-proxied domain
|
||||
to be sent to an IP address that was not assigned by Cloudflare for the domain*。
|
||||
官方保留封号权;社区共识是「用别怕,怕别用」,建议**账号隔离**(主站一个号,优选另开小号)
|
||||
- ⚠️ **要维护**:优选 IP/域名会失效,得定期更换;个别优选域名还会被地方屏蔽
|
||||
|
||||
**路 C · 不违规的优化(零风险,先做)**
|
||||
- ✅ **已做**:字体自托管(`/font/zql-v2.woff2`,无 Google Fonts)、CSS 合并成单文件、图片 WebP
|
||||
- 头像源 `cravatar.cn` 走 CF(0.65s)→ 可换国内源(站内已有 `q1.qlogo.cn` 这类)
|
||||
- 加 **Cache Rules** 长缓存 + **Early Hints** + **Tiered Cache**(免费可用)→ 改善重复访问
|
||||
- 若走第三方 DNS(路 B 顺带),**只下发 A 记录、不下发 AAAA** → 直接规避上面那条差的 IPv6 路由
|
||||
|
||||
### 一句话结论
|
||||
|
||||
**你自己的实测就是答案:国内 CDN 快 2–4 倍,而且完全合规。**
|
||||
CF 免费版在国内的「加速」本质是**可用的灰色技巧 + 持续维护成本**。
|
||||
|
||||
- 如果「只留 CF」是硬目标 → 走 **Worker + 第三方 DNS 只给 IPv4**(比优选 IP 干净,且顺带修 IPv6 问题)
|
||||
- 如果真正的目标是「砍复杂度」→ 记住:**复杂度的大头在「构建与搬运」**(Gitea / act_runner / 中转机 / COS / artifact),
|
||||
**不在 CDN 的数量**。多留一个国内 CDN 不会让架构变复杂;砍掉那串搬运链才会。
|
||||
|
||||
---
|
||||
|
||||
## 六、我的建议
|
||||
|
||||
**先回答那个问题:需不需要「不开电脑也能发文」?**
|
||||
|
||||
| 你的答案 | 选 | 理由 |
|
||||
|---|---|---|
|
||||
| **不需要**(本来就在电脑上写) | **形态 A** | 真正的「只要 CF + Hugo」:0 台服务器、0 个第三方托管 |
|
||||
| **需要**(手机/TG 发文) | **形态 B** | GitLab 只当「代码网盘 + 触发器」,构建和托管全在 CF |
|
||||
|
||||
**两条都不要再去自建 Gitea** —— 那正是你想摆脱的复杂度。
|
||||
|
||||
**一个必须提前想清楚的点**:CF Pages 的 Git 集成与 Direct Upload **不能互转**,项目创建时就要定。
|
||||
如果不确定,**先建 Git 集成项目、之后关掉自动部署用 wrangler 直传**,把两条路都留着。
|
||||
|
||||
---
|
||||
|
||||
## 七、如果还想更彻底(建议不要)
|
||||
|
||||
把内容也搬进 CF:文章存 R2/D1,写作后台写成 CF Worker。但 ——
|
||||
|
||||
**Hugo 构建需要文件系统 + 执行二进制,跑不进 Worker。** 所以要么放弃 Hugo(改成运行时渲染),要么保留一个构建执行者(那就回到形态 B 了)。**复杂度会绕回来,不建议。**
|
||||
|
||||
---
|
||||
|
||||
## 附 A:落地顺序(以形态 B 为例)
|
||||
|
||||
1. GitLab.com 建**私有**项目 → 现有仓库推上去(`.git` 588MB,首次跨境推送需要时间)
|
||||
2. CF Pages 新建项目 → **Connect to Git → 选 GitLab**
|
||||
- 构建命令:`hugo --minify`
|
||||
- 输出目录:`public`
|
||||
- 环境变量:`HUGO_VERSION=0.128.2`(CF 构建镜像默认是 0.147.7,要锁到你的版本)
|
||||
3. 绑定自定义域名 `usj.cc`
|
||||
4. `blog-admin` 保持不动(本来就在 CF)
|
||||
5. 停掉 Gitea / act_runner / 中转机的同步计划任务;DNS 切到 Cloudflare
|
||||
6. **观察国内访问速度** —— 这是唯一的实质性风险点
|
||||
|
||||
## 附 B:形态 A 的落地顺序
|
||||
|
||||
1. 本机装 `hugo` 0.128.2 + `wrangler`(Node 环境已有)
|
||||
2. CF Pages 新建 **Direct Upload** 项目(**注意:一旦选它,以后不能改成 Git 集成**)
|
||||
3. 本机 `hugo --minify && npx wrangler pages deploy public --project-name=<项目名>`
|
||||
4. 绑定域名,完成
|
||||
5. 其余全部关停
|
||||
|
||||
---
|
||||
|
||||
## 附 C:本方案的证据出处
|
||||
|
||||
- Cloudflare 官方文档 *Git integration*:「Pages offers support for GitHub and GitLab」「does not currently support connecting self-hosted instances of GitHub or GitLab」
|
||||
- 同上:「You cannot switch to Direct Upload later」
|
||||
- Cloudflare 官方文档 *Direct Upload*:Wrangler 上传上限 **20,000 文件 / 25 MiB**;拖拽上限 1,000 文件
|
||||
- Cloudflare 官方文档 *Workers Billing and Limitations*:静态资源请求**免费且不限量**,20,000 文件 / 25 MiB
|
||||
- Cloudflare Blog:*Cloudflare Pages 现已提供对 GitLab 的支持*
|
||||
- CF Pages 免费额度:500 次构建/月、1 并发、单次 20 分钟超时
|
||||
- 本站实测:`public/` = 424MB / 3267 文件,最大单文件 12.8MB
|
||||
@@ -0,0 +1,172 @@
|
||||
> 📦 **本文档已归档**(2026-10-06)。它记录的是**当时的评估与方案**,其中的结论可能已被后续决策推翻。
|
||||
> **请勿据此判断当前架构** —— 现行架构唯一事实源是 [`架构总览.md`](../../../架构总览.md)。
|
||||
|
||||
# 阿里云 ESA 评估(对比 EdgeOne)
|
||||
|
||||
> 2026-10-04 · 问题:「阿里云也有个跟 EdgeOne 很像的服务,能不能考虑一下?」
|
||||
> 现状:`usj.cc` 域名 **境外解析在 EdgeOne、境内解析在多吉云**(DNS 分线路)
|
||||
|
||||
## 一、结论先说
|
||||
|
||||
**能考虑,但对你这个站有一条硬伤,直接卡住:ESA Pages 每个项目最多 2000 个文件,你的产物是 3267 个。**
|
||||
|
||||
而 EdgeOne Pages 是 **20000 个**——你只用了 16%。
|
||||
|
||||
所以结论是:**换阿里云 ESA 不是"简化",是"降级到刚好装不下"。**
|
||||
|
||||
---
|
||||
|
||||
## 二、阿里云对标的到底是什么
|
||||
|
||||
| 腾讯云 | 阿里云 |
|
||||
|---|---|
|
||||
| EdgeOne(边缘安全加速平台) | **ESA(Edge Security Acceleration)** —— 就是原来的 **DCDN 改名** |
|
||||
| EdgeOne Pages(Git 导入 + 自动构建 + 静态托管) | **ESA Pages**(也叫「函数和 Pages」) |
|
||||
| Edge Functions / Cloud Functions | **ESA 边缘函数**(V8 Isolate,只支持 JS) |
|
||||
| 节点 | 阿里云 3200+ 边缘节点 |
|
||||
|
||||
**能力确实是同级的**——都免费、都支持 ICP 备案、都能绑备案域名走大陆节点、都是「Git 导入 + 自动构建 + 全球分发」一套。你问得没错,这是对标产品。
|
||||
|
||||
**但两者的尺寸门槛差了 10 倍,这是分水岭。**
|
||||
|
||||
---
|
||||
|
||||
## 三、★ 决定性的一张表:文件数门槛
|
||||
|
||||
我逐个查了官方配额页(不是二手说法):
|
||||
|
||||
| 项目 | **ESA Pages** | **EdgeOne Pages** | Cloudflare Pages |
|
||||
|---|---|---|---|
|
||||
| **单项目文件数** | **2000** ❌ | **20000** ✅ | 20000 ✅ |
|
||||
| 单文件大小 | 25 MB | 25 MB | 25 MiB |
|
||||
| 源码包大小 | 1024 MB | — | — |
|
||||
| 总存储容量 | — | 5 GB | — |
|
||||
| 构建次数 | — | 500 / 月 | 500 / 月 |
|
||||
| 构建超时 | — | 20 分钟 | 20 分钟 |
|
||||
| 构建算力 | — | **4 核 6 GB** | — |
|
||||
| 自定义域名 | — | 200 个 | — |
|
||||
| **你的站** | **3267 → 超限 63%** | 3267 → 占 16% | 占 16% |
|
||||
|
||||
来源:阿里云官方文档《函数和 Pages 使用限制》——*"Pages 文件数 2000 个:每个 Pages 项目最多可上传 2000 个静态文件"*;EdgeOne 官方《限制与配额》——*"单项目文件数 20000"*。
|
||||
|
||||
**这一条把 ESA 从候选名单里筛掉了,其他指标都不用比了。**
|
||||
|
||||
> 附带发现:**EdgeOne Pages 的构建环境是 4 核 6 GB** —— 比你那台广州中转机(2 核 1.9 G)强得多。如果走它的 Git 集成自动构建,hugo 构建完全不需要你自己的机器。
|
||||
|
||||
---
|
||||
|
||||
## 四、你的 3267 个文件是怎么构成的
|
||||
|
||||
```
|
||||
1337 html ← 文章页 + 分类/标签/归档页
|
||||
1211 png ┐
|
||||
295 webp │
|
||||
254 jpg ├─ 图片/视频类合计 1778 个(占 54%)
|
||||
7 mp4 │
|
||||
6 jpeg │
|
||||
3 svg ┘
|
||||
66 xml ← sitemap / rss
|
||||
59 js
|
||||
3 woff2 / 3 woff / 3 mp3 / 3 css / 6 json / 2 txt
|
||||
────────────────
|
||||
3267 总计
|
||||
```
|
||||
|
||||
**纯文本类(html/xml/css/js/json)只有 1473 个** —— 这个数字很关键,它意味着「如果非要用 ESA」还有一条窄路(见第六章)。
|
||||
|
||||
---
|
||||
|
||||
## 五、ESA vs EdgeOne:真实差异(去掉重复项之后)
|
||||
|
||||
免费套餐**大部分能力是重复的**,真正有差别的是这几条:
|
||||
|
||||
| 维度 | ESA | EdgeOne | 谁赢 |
|
||||
|---|---|---|---|
|
||||
| **文件数** | 2000 | **20000** | **EdgeOne(决定性)** |
|
||||
| 大陆节点 | 有(需备案) | 有(需备案) | 平 |
|
||||
| 流量 / 请求 | 不限 | 不限 | 平 |
|
||||
| **开通大陆加速的门槛** | ⚠️ **默认不含大陆,要发帖解锁** | 直接可用 | **EdgeOne** |
|
||||
| 免费套餐数量 | 每账号限 **1 个** | 站点 1 主域 + 200 子域 | EdgeOne |
|
||||
| 构建算力 | 未披露 | 4 核 6 GB | EdgeOne(已知值) |
|
||||
| 单文件限速 | 官方未披露;社区称"不限速",另有称峰值 5 Mbps —— **存疑** | 单文件单线程 4 Mbps(≈500 KB/s) | **ESA 可能赢** |
|
||||
| WebSocket | 免费版**不支持**(第三方实测) | — | EdgeOne |
|
||||
| 速度(第三方实测) | 大陆节点覆盖**更多**、网络速度**更高** | 加速效果更佳、全球覆盖更广(Anycast) | 各有说法 |
|
||||
| 迁移成本 | 要重接一次 | **你已经在用** | **EdgeOne** |
|
||||
|
||||
### 值得注意的两点
|
||||
|
||||
1. **ESA 免费版默认不含中国大陆加速** —— 官方原文:*"By default, this plan does not include Chinese mainland acceleration."* 要解锁得**在任意社交/博客平台发一篇 30 字以上的推荐帖**(带 `#AlibabaCloudESA #ESAPages` 标签 + 官方图),再进群提交链接。你写博客顺手能完成,但这是个**额外操作**,跟"简化"反向。
|
||||
2. **ESA 免费版的「不限速」有矛盾说法** —— 一方说无限速适合大流量,一方说峰值带宽约 5 Mbps。如果你的痛点是那个 12.8 MB 的 mp4(EdgeOne 下首载约 25 秒),这一条**值得实测**,但它是 ESA 唯一可能赢的地方。
|
||||
|
||||
---
|
||||
|
||||
## 六、如果非要用 ESA:唯一的一条路
|
||||
|
||||
把 **1778 个图片/视频剥离到对象存储**(OSS / 又拍云 / 多吉云存储),Pages 只托管 1473 个文本文件 → 落回 2000 以内。
|
||||
|
||||
**但代价是**:多一个存储服务、多一套域名与缓存配置、构建产物要改写图片链接。**这是"增加复杂度"换"换一家厂商",跟你的目标正好相反。**
|
||||
|
||||
不建议。
|
||||
|
||||
---
|
||||
|
||||
## 七、ESA 唯一值得拿的东西(互补用法)
|
||||
|
||||
**如果只是想用阿里云,不要用 ESA Pages,用 ESA 的 CDN 加速能力。**
|
||||
|
||||
ESA 免费版(Entrance plan)本质是**一个不限流量的 CDN**,可以回源到任意源站。它能做的是:
|
||||
- 回源到你的又拍云 / OSS 存储 → 只加速,不托管,**没有 2000 文件限制**
|
||||
- 用 ESA 的**边缘函数**收编现在的 `blog-admin`(CF Workers)
|
||||
|
||||
这确实有个价值:**阿里云一家能同时给你 CDN + Pages + 边缘函数 + 对象存储**,比「EdgeOne + CF Workers + 又拍云 + 多吉云」更统一。
|
||||
|
||||
但这又引入了**第四家厂商**,而你现在的问题恰恰是厂商太多。
|
||||
|
||||
---
|
||||
|
||||
## 八、而且你现在的双线路,其实已经是"简化过"的形态
|
||||
|
||||
你说的「境外 EdgeOne、境内多吉云」,本身就是**分线路 DNS 调度**的结果:
|
||||
|
||||
```
|
||||
usj.cc
|
||||
├─ 境外线路 → EdgeOne(Pages 项目,--area overseas)
|
||||
└─ 境内线路 → 多吉云 CDN(融合 CDN,70+ 节点,20 GB/月免费)
|
||||
```
|
||||
|
||||
**这已经做到了"境内外分流"** —— 跟 EdgeOne 双区域方案想达成的效果是一样的。所以真正的问题不是「CDN 选阿里云还是腾讯云」,而是:
|
||||
|
||||
> **要不要把这两条线合并成一家?**
|
||||
|
||||
- **合并到 EdgeOne**:改一个参数(`-a global`)或建国内站项目 → 砍掉多吉云 ✅
|
||||
- **合并到 ESA**:从零接一次,还撞上 2000 文件上限 ❌
|
||||
- **维持现状**:多一条线,但**不增加架构复杂度**——CDN 数量不等于复杂度
|
||||
|
||||
**注意最后一条**:你架构的复杂度大头在**构建与搬运**(Gitea、act_runner、中转机、COS、artifact 链),不在 CDN 数量。多留一个多吉云,不会让架构变复杂;砍掉那条搬运链才会。
|
||||
|
||||
---
|
||||
|
||||
## 九、建议
|
||||
|
||||
1. **别换 ESA Pages** —— 2000 文件上限是硬伤,你的站 3267,装不下。
|
||||
2. **想收敛到一家,就走 EdgeOne** —— 你已经在用,同一个控制台、同一个项目(`-a global` 实验),或者建个国内站项目。迁移成本近零。
|
||||
3. **多吉云可以留着** —— 它免费 20 GB/月、融合 CDN(依托大厂节点)、速度好,而且它是**独立的国内线路**,跟 EdgeOne 互为备份。不构成复杂度问题。
|
||||
4. **如果哪天站点瘦身到 2000 文件以内**(比如把 1778 个图片全挪到对象存储),ESA 会重新变成候选 —— 但那时 EdgeOne 也一样能用,还是没必要换。
|
||||
|
||||
---
|
||||
|
||||
## 十、待核实项(不装作确定)
|
||||
|
||||
| # | 事项 | 状态 | 怎么验 |
|
||||
|---|---|---|---|
|
||||
| 1 | 多吉云当前的回源源站是谁(又拍云存储 / EdgeOne / 其他) | **待确认** | 多吉云控制台看回源配置 |
|
||||
| 2 | ESA 免费版是否真的"不限速"(vs 峰值 5 Mbps) | **说法矛盾** | 需实测,但没必要为它迁移 |
|
||||
| 3 | ESA Pages 是否支持 Gitee 作为代码源 | 官方只列 GitHub,第三方提到 Gitee | 若成立,对简化链路有价值 |
|
||||
| 4 | EdgeOne Pages 的 Git 集成是否支持 Gitee | 上次标的第 5 条,仍未确认 | 若支持可砍掉自建 Gitea + act_runner |
|
||||
|
||||
---
|
||||
|
||||
## 十一、一句话总结
|
||||
|
||||
**阿里云 ESA 确实是对标 EdgeOne 的产品,能力同级——但 ESA Pages 限 2000 文件,你的站 3267 文件,直接在门口就被拦下。**
|
||||
**换厂商解决不了你的问题;你的问题在构建与搬运链,不在 CDN 选谁。**
|
||||
Reference in new issue
Block a user