- 决策文档:架构总览 / 代码源与构建平台选型 / 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/(工作数据不入库)
174 lines
11 KiB
Markdown
174 lines
11 KiB
Markdown
# 优世界博客 · 架构总览与复杂度审计
|
||
|
||
> 梳理时间:2026-10-04
|
||
> 目的:把「复杂在哪、为什么复杂、哪些是自己加的、哪些能砍」讲清楚,供架构决策。
|
||
> 方法:以代码/配置为证据,不用推测。凡属推测的地方都标了「待确认」。
|
||
|
||
---
|
||
|
||
## 0. 一句话结论
|
||
|
||
**这不是「一个博客」,而是四个独立系统,绑在一条 7 环节、跨境的、需要自己运维的发布链路上。**
|
||
|
||
前三个系统都很轻、也很健康;**复杂度几乎全部来自第四个 —— 为了支撑前三个而自建的基础设施**(Gitea + act_runner + 中转机),以及为了绕过跨境链路而打的一层层补丁。
|
||
|
||
---
|
||
|
||
## 1. 全景:哪里有什么
|
||
|
||
### 1.1 四个子系统
|
||
|
||
| # | 子系统 | 技术栈 | 跑在哪 | 健康度 |
|
||
|---|---|---|---|---|
|
||
| **1** | **内容系统** | Hugo 0.128.2 + Ying 主题,138 篇 md,产物 424MB / 3267 文件 | 产物分发到 3 个 CDN | 主体,正常 |
|
||
| **2** | **评论系统** | `blog-admin/` = artalk-cf(Artalk v2 兼容服务端)+ RSS 机器人 | Cloudflare Workers + D1 + KV → `api.200181.xyz` | ✅ 已上线,**零服务器零运维**,架构最干净的一块 |
|
||
| **3** | **写作系统** | `write-server/`(Next.js 16 + Docker,`post.usj.cc`)<br>`write/`(本地 Windows 前端,带 vbs/bat 自启动) | 独立 Docker 主机(**待确认**)/本机 | ⚠️ **两套前端功能重叠** |
|
||
| **4** | **基础设施** | Gitea 28.0.0 + act_runner + 1Panel 中转机 + 各类备份脚本 | 境外 VPS + 腾讯云广州 | ⚠️ 正在迁移,**复杂度的主要来源** |
|
||
|
||
### 1.2 机器与服务地图
|
||
|
||
| 标识 | 地址 / 位置 | 承担什么 |
|
||
|---|---|---|
|
||
| **Gitea 主机** | `23.254.236.47:3001`(境外) | Git 仓库 + **Gitea Actions / act_runner** + artifact 存储 |
|
||
| **国内中转机** | `119.29.215.187`(腾讯云广州) | 1Panel + OpenResty + mysql + alist + vaultwarden(7 个容器)+ `sync.sh` 每分钟轮询同步 |
|
||
| **EdgeOne Pages** | 项目 `hugo-blog`,`--area overseas` | **境外线路**的托管与 CDN(腾讯) |
|
||
| **又拍云** | 对象存储 | **国内源站** |
|
||
| **多吉云** | CDN,回源又拍云 | **国内加速** |
|
||
| 腾讯云 COS | `cos.ap-*.myqcloud.com` | 曾是「境外构建产物 → 国内中转机」的中转层,**正在砍** |
|
||
| Cloudflare | `api.200181.xyz` | 评论后端 + RSS 机器人 |
|
||
| 通知渠道 | Telegram / 飞书 / QQ 邮件 | 三套并行,内容 90% 重复 |
|
||
|
||
> 关键点:**境外线路和国内线路是完全独立的两套。** 境外走 EdgeOne,国内走 多吉云 → 又拍云。任一篇文章上线,两条链路上的东西都得各自到位。
|
||
|
||
---
|
||
|
||
## 2. 一次发文的完整旅程
|
||
|
||
```
|
||
① 写作 write-server (web) 或 write/ (本地 Windows)
|
||
│
|
||
② 提交 git push ──► Gitea(自建,跨境) ← 你自己维护的机器 1
|
||
│
|
||
③ 构建 Gitea Actions / act_runner ← 你自己维护的 runner 2
|
||
│ ├─ hugo --minify --gc (要的)
|
||
│ ├─ 图片优化 (sharp, 482 张) (可砍,见 §3-C)
|
||
│ └─ 草稿隐藏处理
|
||
│
|
||
④ 传递 424MB 产物 → 打 tar.zst → Gitea artifact ← 踩过 3 个坑才通
|
||
│
|
||
┌────┴─────────────────────────────┐
|
||
▼ ▼
|
||
⑤ 境外线路 ⑥ 国内线路
|
||
EdgeOne Pages 广州中转机 sync.sh(每分钟轮询) ← 你自己维护的机器 3
|
||
(runner 直接 deploy) └─ 跨境下载 376MB
|
||
└─ upx sync → 又拍云
|
||
└─ upx purge
|
||
│
|
||
⑦ 多吉云 CDN 刷新 + TG / 飞书 / 邮件 三套通知
|
||
```
|
||
|
||
**对照**:一个普通 Hugo 博客 + 托管 CI 的发布链路是 **3 步**(push → 构建 → 上线)。
|
||
你这里是 **7 步,中间有 3 个环节是你自己在运维的服务器/服务**。
|
||
|
||
这就是「复杂」最直观的度量。功能一点都不多,**多的是中继环节**。
|
||
|
||
---
|
||
|
||
## 3. 复杂度归因:三层,性质完全不同
|
||
|
||
### A 层 · 外部约束 —— 不是你的选择,但躲不掉
|
||
|
||
| 约束 | 连带出来的复杂度 |
|
||
|---|---|
|
||
| **GitHub 账号被标记** | 自建 Gitea → 连带 act_runner 自运维、artifact API 不合规、缓存服务跨网段不可达 |
|
||
| **跨境链路不稳** | 境外 runner 直传又拍云 v0 API 稳定 EOF → 必须有境内兜底 |
|
||
| **国内 / 境外访问质量不同** | 被迫维护两条独立线路(EdgeOne + 多吉云/又拍云) |
|
||
| **EdgeOne Pages 国际站必须 `--area overseas`** | 部署动作只能从境外发起 |
|
||
|
||
> A 层是**根因**。B、C 两层的大部分,都是 A 层长出来的。
|
||
|
||
### B 层 · 为绕开 A 打的补丁 —— 半被迫,可以简化但不能直接删
|
||
|
||
| 补丁 | 为什么存在 | 代价 |
|
||
|---|---|---|
|
||
| 广州中转机 `sync.sh` 每分钟轮询 | 境外直传又拍云不通 | 多一台机器要维护;每分钟一次轮询;产物要跨境搬一次 |
|
||
| COS 中转层(正在砍) | 给「境外产物 → 国内源站」当缓冲区 | 存储 + 流量账单 |
|
||
| 一套 workflow 硬塞进 Gitea | 原本为 GitHub 写 | **8 处** `github.server_url == 'https://github.com'` 分支判断 |
|
||
| artifact 单文件 tar 化 | v4 不支持 / v3 传目录 finalize 500 | 额外的打包/解包步骤 |
|
||
| 备份脚本三套(aliyun / gitea / cleanup) | 自建基础设施的必然成本 | — |
|
||
|
||
> ⚠️ **一个需要你注意的点**(推测,建议实测):砍掉 COS 之后,中转机变成**直接跨境从境外 Gitea 拉 376MB**。跨境传输这一步并没有消失,只是从「境外 → 境内 COS(一次跨境上传)」变成「境内 ← 境外 Gitea(一次跨境下载)」。**除非实测新链路更快更稳,否则「砍 COS」省的是账单,不是复杂度。** 这条直接关系到你在做的改造是不是真的划算。
|
||
|
||
### C 层 · 自己加的 —— 可以直接砍,收益最大
|
||
|
||
| # | 冗余 | 证据 | 能砍吗 |
|
||
|---|---|---|---|
|
||
| 1 | **图片优化塞进 CI** | `Optimize Images` + `Commit Optimized Images` + `Push Image Optimizations` 三步 + `npm ci` 装 sharp(~50MB)。扫 482 张图,其中 **15 张 2021–2023 的老图永远处理不掉**,每轮重扫重试 | ✅ **最该砍**。图片在写作时本地处理,CI 就永远不需要 sharp |
|
||
| 2 | **CI 反向 commit 回仓库** | `Commit Optimized Images` 把结果 commit,`Push Image Optimizations` 再 rebase push | ✅ 砍掉图片优化后,这两步一起消失 |
|
||
| 3 | **三套通知** | `Send Telegram` ×2 + `Send Feishu` ×2 + `Send email` ×1 = **5 个 step,约占 deploy.yml 的 1/3(~400 行)**,同一份内容写 3 遍 | ✅ 留一套(TG 或飞书),其余删 |
|
||
| 4 | **永久跳过的死代码** | `Upload to UpYun` 标了 `if: false`,但 **~100 行代码仍在**(upx 下载、登录重试、sync 重试) | ✅ 要么删,要么挪进中转机 |
|
||
| 5 | **脚本重复** | `add_draft_to_hidden` 有 `.ps1`(96行) 和 `.py`(110行) 两份,README 写的是 ps1、CI 用的是 py;`deploy_*.sh` 有 4 个共 225 行 | ✅ 各留一份 |
|
||
| 6 | **两套写作前端** | `write/`(本地 Windows)与 `write-server/`(网页)功能重叠 | ⚠️ 看你的使用习惯,可合并 |
|
||
|
||
---
|
||
|
||
## 4. 量化:复杂度有多少
|
||
|
||
| 指标 | 值 |
|
||
|---|---|
|
||
| `deploy.yml` 总行数 | **1169 行** |
|
||
| job 数 | 7 个(含 1 个手动触发的网络探测 job) |
|
||
| 单个 job 的 step 数(finalize) | 12 个 |
|
||
| 通知类 step | 5 个(TG×2 / 飞书×2 / 邮件×1),约 400 行 |
|
||
| `github.server_url` 兼容分支 | 8 处 |
|
||
| `if: false` 死代码 | 约 100 行 |
|
||
| 需要自己运维的机器 / 服务 | **3 个**(Gitea 主机、act_runner、广州中转机) |
|
||
| 发布链路环节数 | **7 步**(理想 3 步) |
|
||
| 涉及的 CDN / 存储 | 4 个(EdgeOne / 又拍云 / 多吉云 / COS) |
|
||
| 构建产物体积 | 424MB / 3267 文件 |
|
||
| 真正发布所需的机器数(理想) | **1 台**(构建 + 推送)或 0 台(托管 CI) |
|
||
|
||
**一句话**:功能是一个静态博客 + 评论 + 写作后台,但支撑它的是 **7 个 job、4 个 CDN、3 台自维护机器、1169 行流水线**。
|
||
|
||
---
|
||
|
||
## 5. 四条可选的收敛方向
|
||
|
||
| | 方向 A · 就地瘦身 | 方向 B · 构建源外包 | 方向 C · 构建下移境内 | 方向 D · 取消 CI |
|
||
|---|---|---|---|---|
|
||
| **做什么** | 砍 C 层:图片优化移出 CI、合并通知、删死代码、合并脚本 | 引入 gitlab.com(GitHub 已被封)或用 CF Pages 构建 | Gitea + runner 迁到广州机,构建发生在境内 | 写作后台直接构建 + 部署,Gitea 退化为纯代码托管 |
|
||
| **产物落地** | 不变 | gitlab.com 共享 runner | 境内直接推又拍云 ✓ | 写作后台直接推又拍云 + EdgeOne |
|
||
| **跨境传输** | 不变 | 视方案 | **只剩 EdgeOne 一步** | 同上 |
|
||
| **新增依赖** | 无 | gitlab.com 账号 + 跨境 push | 无 | 无 |
|
||
| **主要风险** | 只是变短,环节数不变 | **GitLab 免费版仅 400 分钟/月**(你月需约 400–900 分钟,踩线) | 广州机**内存 1.9G / 已跑 7 个容器**,hugo 构建未必跑得动 | 写作后台所在机器算力是否够;构建与发布耦合 |
|
||
| **代价** | 最低,纯收益 | 月额度可能超 | 需要瘦身后实测内存 | 需要改造写作后台 |
|
||
| **建议** | ✅ **先做,是所有方案的前置** | 备选 | 与 D 二选一,实测决定 | 与你「一键直达」的偏好最契合 |
|
||
|
||
### 推荐路径
|
||
|
||
1. **先做方向 A**(无风险、纯收益、且是 B/C/D 的前置)。做完后 `deploy.yml` 预计能从 1169 行降到 600 行以内,构建里只剩 `hugo build`。
|
||
2. **再实测两件事**:① 广州机跑一次 `hugo` 的峰值内存与耗时;② 国内机跑一次 `hugo` 的耗时(对比 CI)。
|
||
3. **依据实测二选一**:
|
||
- 广州机跑得动 → **方向 C**(Gitea 迁境内,跨境只剩 EdgeOne)
|
||
- 写作后台机器跑得动 → **方向 D**(连 CI 都取消,最符合「一键直达」)
|
||
- 都跑不动 → **方向 B**(但要接受 GitLab 400 分钟/月的紧箍咒)
|
||
|
||
---
|
||
|
||
## 6. 需要你决定的三件事
|
||
|
||
1. **那 15 张 2021–2023 的老图能清吗?** 能清的话,我本地转 WebP + 修引用,然后 `Optimize Images` 这一步整个从 CI 删掉 —— 这是砍掉 C 层最大块的钥匙。
|
||
2. **构建最终放在哪一侧?** 境外(现状)/境内(方向 C/D)/外包(方向 B)。这决定后面所有改造的走向。
|
||
3. **通知留哪一套?** TG / 飞书 / 邮件 —— 留一个,其余删。另外邮件通知那份的长文本(约 50 行模板)可以整个去掉。
|
||
|
||
---
|
||
|
||
## 附:本次梳理的证据出处
|
||
|
||
- `.github/workflows/deploy.yml`(1169 行,全文通读)
|
||
- `blog-admin/README.md`、`write-server/README.md`、`write/`(模块定位)
|
||
- `hugo.toml`(`baseURL = https://usj.cc`)
|
||
- `gitea-backup/README.md`、`docker-compose.yml`(迁移目标与坑)
|
||
- `scripts/` 目录清单与行数统计
|
||
- 线上实测:Gitea `/api/v1/version` = `28.0.0`;广州机 `docker pull gitea/gitea:28.0.0-rootless` 可拉、`1.28.0-rootless` 不存在
|