docs(overlay): 覆盖网络/客户端化 10 份规划转正式档案 103-112 + 登记

- 新增 04-调整方案/103-112:可行性评估 · 全球架构复盘 · 骨干层方案 ·
  百台推演 v2 · 千台全场景推演 · 游戏专项 · 游戏网络与群聊上限调研 ·
  答疑(群聊/备份/迁移/保密) · 补遗与参考方案 · 九大瓶颈落地方案
- 每份按 交接单/README.md §二 8 段改写(目标/只读前置/范围/决策点/
  步骤/验收/回滚/回报格式)+ 头部状态标注(📋 规划态 · 未实施)
- 技术内容不变:附录 A 逐字保留原文全文(仅去其一级标题),已逐份校验字节一致
- 登记:INDEX.md §二 +10 行、03-路线图与待办.md §二 +1 行
- 收尾:docs-audit.py 退出码 0(无 P0)· docs-manifest.py 已刷新
- 本轮零代码、零服务器改动;⛔ 未 push
- 占号:103-112(先原子 mkdir .lock-<NN> 再写)
This commit is contained in:
admin committed 2026-09-16 10:25:09 +08:00
1 parent cb184145e9
commit 4e3a1a4a13
13 files changed
+2670 -22

No files matched your search

+1
View File
@@ -104,6 +104,7 @@
| ❌已复核 | ~~Cookie 域收窄~~ | **不做(2026-09-12 用户决定:把这条待办删掉)** —— 共享 Cookie(`Domain=.alotbuy.com`)是**有意设计**:支撑「功能插件 ↔ 门户」**免令牌鉴权**(配合 `server.ts` 的 CORS 白名单),功能插件 v0.2.1 已生产跑通 → **收窄会破坏该链路,收益为零**;结论见档案 05 PoC-2 ② |
| 🟡 **待排期** | **T08 集群化的收尾项**(主体与生产切换已完成) | ① `join-worker.sh` 一键装机(现在 join = 装 unit + 起 agent + 注册,三步手工)~~② 隧道服务化~~ ✅ 已收口(本地 20s 定时器自愈,实测 30s 内恢复)③ 集中日志 / metrics ④ `smoke-domain` 定性 ⑤ drop-in 里的 PG 口令建议进一步收权限(现 root 可读)|详见 `交接单/T08 §16.5` |
| 🟡 **待排期** | **覆盖网络 / 客户端化这条线**(**本轮零代码、零服务器改动**) | 已落 **档案 103–112**(10 份规划转正式档案;入口 = 工作区根 `接续入口_覆盖网络线_20260916.md`)。📌 **第一件实事 = 把会合 / 中继从 Manager 里拆成可独立部署的组件**(现为绑在 Manager 上的**单中心 SSH 反向隧道**;所有后续多区域 / 多中心 / 骨干层的前置)。**已定口径**:只做技术实现(跨境合规由使用者自负)· **单机自用 ≠ 不需互联** · 按**异构**设计(中继 45% 设计 / 55% 留余量 + **必须补 443/TCP 兜底**)· 权威状态(归属 / 租约 / 资格)**必须单点控制面** · 游戏重点 = **MMORPG(2D/2.5D) / MUD / 传奇类**。⚠️ **唯一待拍板 = 骨干节点服务范围**(A 只服务自己名下设备 / B 服务全网;**倾向 A→B 渐进**,见档案 105 §七)。之后按 **档案 112「只做三件事」** 开工 |
### 历史决策记录(保留,均已落地)
@@ -0,0 +1,241 @@
# 103 · 客户端安装与覆盖网络互联 · 可行性评估
- 日期:2026-09-16 | 状态:📋 **规划态 / 未实施**(本轮零代码、零服务器改动;本档=设计单,尚未开跑)
- 来源:工作区根 `可行性评估_客户端安装与覆盖网络互联_20260916.md`(2026-09-16 转为正式档案,正文见 附录 A)
- 层级:**决策层 · 总纲**(本线其余 9 份档案的共同前置)| 关联:档案 104 · 106–112
- 触发(用户原话):「当前项目是否可以改造为支持服务部署以及客户端安装(客户端壳套服务器项目),让他们通过覆盖网络互联」
> **TL;DR**
> ✅ **可行,且现有架构已给出约 80% 的形状** —— T08 集群化已经把「一台机器 = 一个可被平台拨入的执行体」定义完了,
> 并已有两条现成能力正好解决「没有公网 IP」:① `soft` 隔离模式下实例**只是一个普通子进程**(不需 root / bwrap / systemd);
> ② Worker 用**拨出式 SSH 反向隧道**接入 Manager —— **节点本来就不需要公网 IP**。
> 真正的缺口 4 条:**客户端运行时落点 · 节点身份(现为共享令牌)· 信任模型反转 · 分发与版本矩阵**。
## 一、目标
判定「平台能否支持『服务部署 + 客户端安装 + 覆盖网络互联』」,并给出**可增量落地的形态与顺序**、**缺口清单**、**未验证项诚实清单**。
可判定「做完了没有」= 产出 ① 形态结论(A/B/C 三档取舍)② 缺口 4 条 ③ 若走 B 档的 6 步落地顺序(每步可单独回滚)。
## 二、只读前置
> 执行前必须先核实的 5 条事实(**均已在本轮取证过,给出可复跑命令**):
| # | 事实 | 核对方式(期望输出) |
|---|---|---|
| 1 | `soft` 是默认隔离档 ⇒ 实例 = 裸子进程 | `grep -n "isolationMode" src/config.ts` → `'soft' \| 'account'`,默认 `soft` |
| 2 | soft 下不 bwrap / 不 setpriv / 不 systemd-run | `sed -n '660,665p' src/supervisor/orchestrator.ts` → 直接 `spawn(command,args)` |
| 3 | Worker 走**拨出式**反向隧道(节点无需公网 IP) | `sed -n '147,155p' src/worker/tunnel.ts` → `ssh -O forward -R <port>:127.0.0.1:<port>` |
| 4 | 全仓**仅一处**平台分支 | `grep -rn "process.platform" src` → 1 处(`src/supervisor/firewall.ts`) |
| 5 | 节点身份现为**共享令牌 + bearer 比较**(无吊销) | 读 `src/worker/agent.ts` 头部注释(自陈「仅内网 + nft 白名单」) |
## 三、范围
- **改什么**:仅**新增**(新客户端形态 + 新 Spawner 实现 + 新节点身份机制)。**服务端现有路径不动**。
- **不动什么**:⛔ 不改官方 dsh 主程序与缓存(R2)|⛔ 不改管理面(门户 / DB / 归属 / 租约留在服务器)|⛔ 本轮不动服务器、不改代码。
- **红线约束**:R5(权限只准收窄 —— 客户端形态下不得下发平台级凭据)|R2|R1(不自动升级 dsh)。
## 四、决策点
**已定**
1. **形态已拍板 = 单机自用**(用户原话:「考虑用户自己使用就可以了,不用考虑当作服务器 其他人访问」)⇒ 本档 §三 的 A/C 两档「多人维度」**已放弃**,三档表保留为**历史决策依据**,不再是待拍板项。
2. **地基 = `soft` 隔离档**(用户已定:「隔离档保持默认 soft」)—— 三份客户端文档同向。
**历史决策依据(本档 §三,已不再是开放问题)**:A 只做壳(覆盖网络用不上)|**B 自带实例(本档倾向)**|C 客户端当集群 Worker(需强身份 + 重划合规边界)。
**待执行会话复核(非上抛项)**:`soft` 模式在 Windows / macOS 上的实际隔离强度与可运行性 —— **本档已实测修正**:真正的硬阻塞**不在 dsh 运行时**,而在**平台自己的启动方式**(裸名 `spawn('npm')` 在 Windows 报 `ENOENT`;显式 `.cmd` 被 Node 拒 `EINVAL`;改 `cmd.exe /c` 或 `shell: true` 即通)⇒ **代价 = 一处调用方式**。
## 五、步骤(若走 B 档;每步自带一次验证)
1. **验证 dsh 在 Windows / macOS 可运行性**(只读 + 本地装,不动服务器)→ 验证:客户端能起实例 + 实例内 bash 工具可用。
2. **客户端节点代理**(复用 agent 协议、落 `soft`)—— 先只做 `/healthz` `/launch` `/stop` `/fence` → 验证:台账式幂等(同 `operationId` 重放不产生副作用)。
3. **通道**:先用现有**拨出式 SSH 反向隧道**打通(零新依赖,当天可验)→ 验证:无公网 IP 的节点可被平台访问。
4. **身份**:每节点独立凭据 + 吊销(替换共享 bearer)→ 验证:吊销单台后该台拨入被拒,其余不受影响。
5. **强约束落码**:实例所属 == 客户端主人;**共享密钥不下发客户端**(红线级)→ 验证:断言/测试钉住,构造越权用例必须失败。
6. **分发与自动升级** + 客户端 × 平台版本兼容矩阵 → 验证:旧客户端连新平台给出可读的「需升级」而非崩。
## 六、验收
| # | 口径 | 期望 |
|---|---|---|
| A | 可行性判定 | 已给出(✅ 可行 + 80% 形状 + 缺口 4 条)—— 本档已交付 |
| B | 形态可选性 | 三档各有优缺、含倾向(B),且**已按用户口径收窄为单机自用** |
| C | 落地可执行性 | 6 步,**每步可单独回滚**,且第 1 步不依赖服务器 |
| D | 未验证项透明 | §五 五条未验证项已列全(Windows/macOS 起实例、soft 实际隔离强度、共享密钥能否按形态裁剪、打洞替换代价、版本矩阵判据) |
## 七、回滚
- **本档自身**:零改动 ⇒ 无回滚需要。
- **若按 §五 执行**:全程**只新增**(新客户端形态 + 新 Spawner 实现),**服务端现有路径不动** ⇒ **删客户端即回到现状**。
- 服务器侧待复核事实(非本档动作):控制面机规格(1.8 GB / 2 核 是 09-08 旧记录);47↔106 跨云实测 **~22 KB/s**。
## 八、回报格式
执行会话回填:① 每一步的验证命令 + 实际输出 ② 触及的文件清单(应与 §三 一致,多出来的要说明)③ 红线遵守声明(R2 官方包零改动 / R5 未下发平台凭据)④ commit ⑤ 未完成项与卡点(附客观依据)⑥ 若推翻本档任一结论,给出取证。
## 九、本档需收口的两处(**未处理,仅报告**)
1. **双源声明**:`dsh客户端化部署方案_20260916.md`(v3)自称「'客户端化'的**单一来源**」,而 `dsh桌面客户端_开发方案_20260916.md`(v1)与其同日并存且**不同层**(平台侧 vs 交付载体层)⇒ 属「第二个漂移源」风险。建议:v3 定平台侧、v1 定交付层,v3 补一行指针指向 v1。
2. **判定句互相矛盾**:v3 §12 附录 C 把「官方桌面版(Electron)作为载体」列为**放弃项**,而 v1 恰恰选了这条路(且其「保留壳、换内核」已实际消解该理由)⇒ 并列阅读会读成"同一件事既放弃又采纳"。建议在 v3 §12 该行加注「已被 v1 以'换内核'方式规避,判定失效」。
> ⚠️ 这两处**不在本档 lane**(两份文档已收口、只读),仅报告不代改。
---
## 附录 A · 原始规划正文(逐字保留 · 2026-09-16)
> 以下为工作区根 `可行性评估_客户端安装与覆盖网络互联_20260916.md` 的**原文全文**,仅删除其一级标题(避免与档案标题重复),
> 其余**一字未改**;本档的可判定部分以上方 8 段为准。
> 日期:2026-09-16 | 状态:**调研稿**(只读取证完成,未改任何代码/服务器)
> 触发:用户问「当前项目是否可以改造为支持服务部署以及客户端安装(客户端壳套服务器项目),让他们通过覆盖网络互联」
> ⚠️ **本稿落点说明**:文档库(`dsh-server-docs/`)当时被**全局执行锁**占用(持有者 `guest迁移-2307`,09-15 23:08 起)⇒ 按纪律**未写入文档库**,暂落工作区根。锁释放后应转为 `04-调整方案/<NN>-*.md` 正式档案并登记。
---
## TL;DR
**可行,而且现有架构已经给出约 80% 的形状** —— 因为「一台机器 = 一个可被平台拨入的执行体」这件事,T08 集群化已经定义完了,并且**已经有两条现成能力**正好解决"没有公网 IP":
① `soft` 隔离模式下实例**只是一个普通子进程**(不需要 root / bwrap / systemd);
② Worker 用**拨出式 SSH 反向隧道**接入 Manager —— **节点本来就不需要公网 IP**。
真正的缺口是 4 条:**客户端运行时落点**、**节点身份(现为共享令牌)**、**信任模型反转**、**分发与版本矩阵**。
---
## 一、现成资产(可直接复用 · 均带代码坐标,已核实)
| # | 资产 | 证据 | 为什么关键 |
|---|---|---|---|
| 1 | **`soft` 隔离模式**:实例 = 裸子进程 | `src/supervisor/orchestrator.ts:663` —— `isolationMode !== 'account'` 时直接 `spawn(command, args)`,**无 bwrap / 无 setpriv / 无 systemd-run / 不需要 root**;`src/config.ts:14,180`(`'soft'|'account'`,**默认 `soft`**) | 客户端侧不需要任何特权即可承载实例;Linux 隔离层(bwrap·scope·uid)是**可选增强**,不是前置依赖 |
| 2 | **Worker agent 协议**(≈ 现成的"节点契约") | `src/worker/agent.ts` 头部 4 条纪律:**单向拨入**(不反向连 Manager、不写控制面)· **幂等键 `operationId`** · **最小接口白名单** · **self-fencing(epoch 落后即自停)**;端点:`/healthz` `/launch` `/stop` `/status` `/endpoint` `/fence` `/watchdog` `/fs/*` | 「个人电脑作为节点」所需的核心语义**已经定义并跑通过**(S0–S7 全绿 + 真跨机演练) |
| 3 | **拨出式反向隧道**(解决无公网 IP) | `src/worker/tunnel.ts:152` —— `ssh -O forward -R <port>:127.0.0.1:<port>`;含 20 s 本地定时器自愈(T08 §16.5 ②) | 节点**主动拨出**即可被平台访问,**无需公网 IP、无需端口映射** —— 这正是覆盖网络"中继支"的等价物 |
| 4 | **归属/租约分层判据** | 集群化设计 §1.3:**归属与租约只有 Manager 能写**;Worker 自有本地库 | 客户端天生**只能是数据面**,不会出现"客户端写权威状态"的脑裂 —— 与"个人电脑不可信"天然相容 |
| 5 | **Spawner 接口已抽象** | `src/supervisor/spawner.ts`(`launch / stop / list`)+ `local-*` / `remote-*` 两个实现 | 新增一种"客户端节点"= **多一个 Spawner 实现**,不是改内核 |
| 6 | **平台无跨平台分支** | 全仓仅 `src/supervisor/firewall.ts:42` 一处 `process.platform === 'linux'`(且仅用于 nft 联网护栏) | 除隔离与防火墙外,**代码本身跨平台** |
**结论**:能移植的不是"平台",而是**实例运行时 + 节点代理**这两块;管理面(门户/DB/归属/租约)留在服务器不动。
---
## 二、缺口(4 条,按必须先解决排序)
### 缺口 1 · 客户端运行时落点(技术,自决范围)
- Linux 侧原语分布(已清点):`bwrap`(`orchestrator.ts` / `spawner.ts` / `agent.ts` / `cli.ts` / `routes/admin.ts`)· `systemd-run`(`cli.ts` / `orchestrator.ts`)· `setpriv`(`cli.ts` / `config.ts` / `orchestrator.ts` / `routes/business-plugins.ts`)· `nft`(`cli.ts` / `config.ts` / `orchestrator.ts` / `agent.ts`)· 绝对路径 `/var/lib/dshs` `/opt/dshs` `/usr/local/dsh-runtime`。
- ⇒ 客户端侧需要一套**平台无关的落点**:Node + `dsh` 可执行 + profile + 工作区目录(Windows 用 `%LOCALAPPDATA%`、macOS 用 `~/Library/Application Support`)。
- ⚠️ **未验证(须实测)**:`dsh` 自身在 Windows / macOS 上的**沙箱后端行为**。Linux 侧注释显示 dsh 有"沙箱后端探针",探针失败会 `refusing to run the command unconfined`(实例内 bash 被整体拒绝)—— Windows / macOS 上走哪条后端、是否可用,**尚无证据**。
(验收口径 L2 起:客户端上起一个实例 → `curl` 实例页 200 + 实例内跑一次 bash 工具。)
### 缺口 2 · 节点身份(现在是共享令牌,公网上不成立)
- 现状自陈(`agent.ts` 头部):token 是**共享密钥 + bearer 式比较**,"仅内网 + nft 白名单";HMAC / 防重放**留待后续**。
- 个人电脑在公网 ⇒ 共享令牌**无法吊销单个节点**、无法抗重放、一台泄露等于放行全部。
- ⇒ 必须升级为**每节点独立身份**(客户端证书 / 独立密钥对)+ 准入与吊销,且**通道本身要端到端加密**。
### 缺口 3 · 信任模型反转(最重要的一条,不是技术问题而是边界问题)
- 现平台假设:**宿主机由我们掌控**(所以用 uid 隔离"用户 A 防用户 B")。
- 客户端形态下:**宿主机由用户掌控** ⇒ 原有隔离语义在"防机器主人"这一维上**直接失效**(机器主人本来就能读自己机器上的一切)。
- ⇒ 必须新增硬约束:**一台客户端上的实例只能属于该客户端的主人**;平台**不得**把别人的实例、别人的数据、或平台级凭据下发到客户端。
- ⚠️ 现状反例:平台会把**共享模型密钥**注入实例(档案 85/87 的两层密钥中的"共享"那一层)—— 下发到用户掌控的机器等于**把平台密钥交给用户**。
- ⇒ 客户端形态**必须只用"用户自己的密钥"这一层**;共享层只在服务端实例上使用。
### 缺口 4 · 分发与版本矩阵(运维)
- 客户端安装包 + 自动升级 + **客户端版本 × 平台版本兼容矩阵**(现有 `plugin-compat` / `dsh-install.ts` 是同类问题的服务端解,需要客户端版对应物)。
- 客户端一多,**故障面从"我们的机器"扩到"用户的机器"**(系统时间、磁盘、杀软、代理),排障成本上升。
---
## 三、形态三档(**真取舍,需用户拍板**)
> 判据:三档的**最终效果**对用户完全不同(数据在哪、算力归谁、谁能调度),属"业务目标与优先级",不能由技术标准裁决。
**A 档 · 客户端只做"壳"(远程访问)**
- 优点:改动最小;安全模型**零变化**;不引入任何跨租户风险;沿用现有实例与全部隔离。
- 缺点:个人电脑**不成为节点**,算力仍在服务器;离线不可用;覆盖网络在这一档**没有实际用途**。
**B 档 · 客户端自带"自己的实例"(平台退化为控制面 + 中继 + 目录)**
- 优点:数据与算力都在用户自己机器上,**服务器成本大降**;离线可用;能用到本机文件与本地软件;不引入跨租户风险(每位用户只碰自己的机器)。
- 缺点:`soft` 模式隔离强度**低于**现在的 `account` 模式(本机场景可接受,但需明确边界);Windows / macOS 运行时**未验证**;平台对实例的可控性下降(升级、清理、取证都要客户端配合)。
**C 档 · 客户端作为集群 Worker(平台可把实例调度到用户机器)**
- 优点:算力可横向扩张且复用**已跑通的集群协议**(agent 四纪律 + 归属/租约分层已就位);对平台运营方收益最直接。
- 缺点:**信任模型反转**(别人的代码、别人的数据、平台凭据落到用户掌控的机器上);必须有节点准入 + 吊销 + 强身份;**合规与责任边界要重新界定**;Windows / macOS 的隔离层基本**要从零做**(无 bwrap / 无 systemd / 无 uid 隔离)。
**我的倾向:先做 B**(唯一一档能"增量落地 + 不引入跨租户风险",且正好吃满资产 1/3/4 的现成能力)。A 档价值有限(覆盖网络用不上);C 档应等服务端能力与合规边界都清楚后再谈。
---
## 四、若走 B 档:落地顺序(每步可单独回滚)
1. **验证 dsh 在 Windows / macOS 的可运行性**(只读 + 本地装,不动服务器)——产出:能否起实例 + 实例内 bash 工具是否可用(L2/L4)。
2. **客户端节点代理**(复用 agent 协议,落 `soft` 模式):先只做 `/healthz` + `/launch` + `/stop` + `/fence`,台账式幂等。
3. **通道**:先用现有**拨出式 SSH 反向隧道**打通(零新依赖,当天可验),再评估换"打洞优先 + 中继兜底"。
4. **身份**:每节点独立凭据 + 吊销(替换共享 bearer)。
5. **强约束落码**:实例所属 == 客户端主人;共享密钥不下发客户端(**红线级**,须有断言/测试钉住)。
6. 分发与自动升级。
**回滚**:全程只新增(新客户端形态 + 新 Spawner 实现),**服务端现有路径不动** ⇒ 删客户端即回到现状。
---
## 五、未验证 / 待确认(诚实清单,勿当已知)
| # | 项 | 状态 |
|---|---|---|
| 1 | `dsh` 在 Windows / macOS 起实例 + 实例内 bash 是否可用 | ⚠️ **未验证**(本轮无对应环境) |
| 2 | `soft` 模式下实例的实际隔离强度(能读到宿主什么) | ⚠️ **未验证**(本轮只读了代码分支,未实测) |
| 3 | 客户端形态下"共享密钥不下发"是否已有现成开关 | ⚠️ **待查**(档案 85/87 是两层密钥,需确认能否按形态裁剪) |
| 4 | 打洞优先方案与现有隧道的替换代价 | 📋 方案调研(见同日讨论结论:自托管 NetBird / headscale + 自建中继) |
| 5 | 客户端 × 平台版本兼容矩阵的判据 | 📋 待设计(可仿 `plugin-compat`) |
---
## 附:本轮取证命令(可复跑)
```bash
cd /d/github/dsh_shenxian
sed -n '660,665p' src/supervisor/orchestrator.ts # soft 模式 = 裸 spawn
grep -n "isolationMode" src/config.ts # 'soft'|'account',默认 soft
sed -n '1,30p' src/worker/agent.ts # 节点四条协议纪律
sed -n '147,155p' src/worker/tunnel.ts # -R 反向转发(拨出式)
grep -rn "process.platform" src # 全仓仅 1 处(firewall.ts)
```
---
## 六、与另两份客户端文档对账(2026-09-16 08:5x 追加)
> 对账对象(同为大工作区根,**均晚于本稿 8 小时**,08:06 产出):
> `dsh客户端化部署方案_20260916.md`(v3 · 单机自用 · 自称「客户端化」的单一来源)
> `dsh桌面客户端_开发方案_20260916.md`(v1 · 基于官方 Electron 壳 · 独立仓库)
### 6.1 结论:**不冲突,是互补;但两处需要收口**
| 维度 | 本稿 | 部署方案 v3 | 桌面客户端 v1 | 判定 |
|---|---|---|---|---|
| 形态选择 | 三档 A/B/C,倾向 **B** | **单机自用**(用户原话已定,§12) | 单机自用为默认,域名可切多人 | ✅ **同向**(本稿的 B 即其单机自用;三档问题已被用户拍板,见 6.2) |
| 地基 | 资产 1:`soft` 默认、无需 root | 明确"隔离档保持默认 soft" | 同 | ✅ 互相印证 |
| 平台改动面 | 资产 6:仅 firewall 一处平台分支 | "唯一硬阻塞 = spawn 方式" | P1 同一条 | ✅ 不同维度,可并存 |
| 分发与版本 | 缺口 4 | — | §3.4 上游同步 / §4.6 自动更新 / §6 打包 | ✅ 已被其覆盖 |
### 6.2 本稿需修正的两点(**如实记录,勿当原判**)
1. **缺口 1 的位置标错了**:本稿把"客户端运行时"列为缺口、并怀疑 `dsh` 在 Windows 的**沙箱后端**不可用。部署方案 v3 **已在本机 Windows 实测**:真正的硬阻塞是**平台自己的启动方式** —— 裸名 `spawn('npm')` 在 Windows 报 `ENOENT`(全局包是 `.cmd`),显式 `.cmd` 被 Node 拒(`EINVAL`),改用 `cmd.exe /c` 或 `shell: true` 即通。⇒ **阻塞点在平台调用层,不在 dsh 运行时**,且**代价很小**(一处调用方式)。
2. **三档"需用户拍板"已不再是开放问题**:用户此前已定「考虑用户自己使用就可以了,不用考虑当作服务器 其他人访问」⇒ **A/C 两档的多人维度已被放弃**。本稿第五节的三档保留为**历史决策依据**,不再是待拍板项。
### 6.3 仅本稿覆盖、另两份未涉的:**覆盖网络**(用户最初问题里的那一项)
- 两份文档的"多人形态"路线 = **内网 DNS 泛解析 + 域名**(局域网内多机访问),与"覆盖网络"是**同一需求的两种替代实现**:
- 局域网 + 域名:只能在同一内网;跨公网不行;需要域名与 DNS 泛解析。
- 覆盖网络:跨公网可直连(打洞优先、中继兜底);不需要域名;但需要客户端常驻 + 节点身份。
- ⇒ **本稿与另两份文档在"能力面"上不冲突,但在"要不要跨公网互连"上是分叉**;两份文档默认不跨公网。若确定不做跨公网,本稿的缺口 2/3 可整体降级为"不适用"。
- 📄 **百台规模的逻辑预演见 `覆盖网络_百台规模推演_20260916.md`**(2026-09-16):结论 = 100 台规模下**控制面不是瓶颈,中继带宽与"大流量过网"才是**(实例首屏含 ≈10.8 MB 客户端脚本);而"单机自用"天然把大流量留在回环上 ⇒ 该形态在 100 台规模下是**正确版而非妥协版**。
### 6.4 两处需收口的隐患(**建议进文档库时一并处理**)
1. **双源声明**:部署方案 v3 自称「'客户端化'的**单一来源**」,而桌面客户端 v1 与其**同日并存**且内容不同层(平台侧 vs 交付载体层)⇒ 属项目明令禁止的"第二个漂移源"风险。建议:**v3 定平台侧、v1 定交付层,v3 里补一行指针指向 v1**,或合并。
2. **判定句互相矛盾**:v3 §12 附录 C 把「官方桌面版(Electron)作为载体」列为**放弃项**(理由:换载体会丢掉门户能力),而 v1 **恰恰选了这条路**。v1 的"保留壳、换内核为我们的平台"已实际**消解**该理由(门户能力并未丢),但 **v3 的判定句未更新** ⇒ 并列阅读时会读成"同一件事既放弃又采纳"。建议在 v3 §12 该行加注"已被 v1 以'换内核'方式规避,判定失效"。
### 6.5 本稿的**缺口 3 仍然有效,且是"切多人形态时的前置门禁"**
- 部署方案 v3 §1.3 明确写:切多人形态**零代码**(只配域名),且**多人时隔离档仍是 `soft` ⇒ 用户之间无隔离**;桌面客户端 v1 §4.7 进一步要求"**客户端 spawn 平台时不要清理环境变量、不要白名单化**"(为透传域名)。
- 这两条与本稿缺口 3 的硬约束**正面相交**:
- ① **实例只能属于机器主人** —— 单机自用下天然成立;一旦配域名多人用,**立刻不成立**(soft 档无隔离)。
- ② **平台级共享模型密钥不得随客户端分发** —— 与"环境变量原样继承"相冲。**建议改为白名单透传**,只放形态开关三项(`DSHS_BASE_DOMAIN` / `DSHS_COOKIE_DOMAIN` / `DSHS_SECURE_COOKIES`),模型密钥只走"用户自己的密钥"那一层。
- ⇒ 结论:**不是"不兼容",而是"范围收窄把风险面暂时关掉了、但开关就在配置里"**。建议把上述两条写成**切多人形态的前置检查项**(而非留在散文里)。
@@ -0,0 +1,266 @@
# 104 · 覆盖网络 · 全球架构复盘
- 日期:2026-09-16 | 状态:📋 **规划态 / 未实施**(架构复盘稿;未接入任何机器、零代码改动)
- 来源:工作区根 `覆盖网络_全球架构复盘_20260916.md`(正文见 附录 A)
- 层级:**决策层 · 架构总纲**(五层架构 + 风暴类型学 + 流量组织)| 承接:档案 103 · 106;被 107 · 108–112 引用
- 触发(用户原话):要**覆盖全球、用户之间互联互通**的完整架构;**重点:避免网络流量风暴 + 有效组织流量上传与接收**
> **TL;DR**
> ✅ **有完整可循的工程路径** —— Tailscale / ZeroTier / Nebula / libp2p / BitTorrent 已反复验证过,**关键是照抄它们踩过的坑,而不是自己发明**。
> 五层架构(控制面 / 会合 / 骨干·中继 / 数据面 / 观测)+ **10 类风暴类型学** + **流量组织五原则** + 7 步落地顺序。
> 🔑 三句结论:**控制面与数据面必须彻底分离**;**失败不要变成重试**(退避 + 抖动 + 判死);**放大点必须前置治理**。
## 一、目标
给出「全球覆盖 + 用户间互联」的完整架构与**防风暴**的组织方式。可判定「做完了没有」= 五层职责明确、10 类风暴各有处置、流量预算表可算、落地顺序可排。
## 二、只读前置
| # | 事实 | 核对方式(期望输出) |
|---|---|---|
| 1 | 现有中继 = **绑在 Manager 上的 SSH 反向隧道(单中心)** ⇒ 必须先拆组件 | 读 `src/worker/tunnel.ts`(`ssh -O forward -R`)+ 集群化方案 §1.3 |
| 2 | 节点身份现为**共享密钥**(不满足「一机一身份 + 可吊销」) | 读 `src/worker/agent.ts` 头部自陈 |
| 3 | 现有心跳 **20 s** 正好落在 NAT 老化安全区间内 | 读 `src/worker/tunnel.ts` 自愈定时器 |
| 4 | 客户端首屏 bundle **≈10.8 MB**(实测 `11,363,655 B`)⇒ 冷启动风暴的量级来源 | 抓壳页 `/plugins/` 产物计字节(档案 97 同源) |
| 5 | 归属 / 租约 / 骨干资格**只能单点控制面写** | 集群化设计 §1.3(权威状态单点) |
## 三、范围
- **改什么**:⏳ 尚未开跑。方案面 = 拆会合/中继为独立组件 · 换传输 · 换身份 · 补 443/TCP 兜底 · 上参数表 · 内容寻址 + 分级缓存 · 骨干层 + 观测。
- **不动什么**:⛔ 官方 dsh 主程序(R2)|⛔ 单点控制面语义(归属/租约/资格签发**必须单点**,不得下放)|⛔ 本轮不动服务器。
- 🟢 **范围声明(2026-09-16 用户定)**:**本方案只考虑技术实现;跨境数据合规由使用者自行考虑。**
① 技术选型**不为合规让路**(多区域就近部署是**性能**最优的结果,不是合规动作);
② 跨境**不设限**(不做地域封禁、不做数据落地/留存约束);
③ **后续读者 ⛔ 不要再把合规 / 数据主权 / 备案当作本方案的前置条件、约束或上抛项**。
## 四、决策点
**已定**
1. **只做技术实现,合规由使用者自负**(用户原话,见 §三 范围声明)⇒ ⛔ 不得再上抛合规项。
2. **控制面 / 数据面彻底分离**(业内实测支撑:控制面挂掉时节点用内存 netmap 继续跑,已有连接不断)。
3. **骨干/中继是限额资源**(预约 + TTL + 配额),不可无限使用。
4. **可见性默认最小**(接入 ≠ 可见)。
**待拍板(唯一一项,真取舍)**:**骨干节点的服务范围** —— A 只服务自己名下设备(优点:无资源/计费纠纷、权限面不变;缺点:骨干少、冗余低)| B 服务全网(优点:骨干多、可用性高、中继容量易满足;缺点:他人流量跑在你的机器上、元数据暴露、被攻破影响面大)。**倾向 A→B 渐进**。详见档案 105 §七。
## 五、步骤(§八 落地顺序,每步自带一次验证)
1. **拆出会合 / 中继为独立组件**(脱离 Manager)→ 验证:Manager 重启不影响已有数据面连接。
2. 换传输:SSH 隧道 → **单进程多对端**隧道 → 验证:常驻内存下降 1–2 个数量级。
3. 身份:**一机一钥 + 吊销 + 自报网络画像** → 验证:吊销单台生效、其余不受影响。
4. 补 **443/TCP 兜底**通道 → 验证:封 UDP 环境(企业网/校园网)下仍能接入。
5. 上**限流与退避参数表**(§5.2)+ 连接水位/宽限期/扇出上限 → 验证:压测下无重试风暴。
6. **内容寻址 + 分级缓存** → 验证:版本发布时回源字节数 ≈ 1 份 × 组数。
7. 骨干层(多中心 + 选择性加入,见档案 105)+ **观测与容量告警**。
## 六、验收
| # | 口径 | 期望 |
|---|---|---|
| A | 12 条必须内建特性 | 逐条可对照(本档 §2 已列);实施后逐条给证据 |
| B | 10 类风暴 | 每类有「成因 → 触发 → 处置」,且处置落到参数与上限 |
| C | 流量预算表 | 每类流量有「频率 / 单次 / 放大后 / 上限手段」四列,可算 |
| D | 直连成功率 | 作为一等指标被采集(业内口径 >90–94%,本环境未实测) |
| E | 未验证项透明 | §九 六条已列全(网络类型占比、打洞成功率、自有中继收益、中继出口带宽、控制面规格、~~合规~~已出范围) |
## 七、回滚
- **本档自身**:零改动 ⇒ 无回滚需要。
- **执行期**:按 §五 顺序,**每步可单独回滚**(拆组件 / 换传输 / 换身份 / 补兜底各自独立);⛔ 但**归属/租约单点语义不得回滚**(那是红线,不是开关)。
## 八、回报格式
执行会话回填:① 每步验证命令 + 实际输出 ② 参数表落地值(并与 §5.2 逐项对照)③ 红线遵守声明(R2 / 单点控制面 / 接入≠可见)④ commit ⑤ 未完成项与卡点 ⑥ 若实测推翻推演数字,给出实测口径。
## 九、未验证项(勿当结论)
各网络类型实际占比(推演设定)|本环境实测打洞成功率(未实测)|自有中继的性能收益(业内 −150 ms / 12.5×,**本环境未复现**)|中继出口带宽与链路质量(未实测,跨云 22 KB/s 只能作下界)|控制面机规格(1.8 GB / 2 核,**待复核**)|~~跨境传输合规口径~~ ⏹ **已出范围**。
---
## 附录 A · 原始规划正文(逐字保留 · 2026-09-16)
> 以下为工作区根 `覆盖网络_全球架构复盘_20260916.md` 的**原文全文**,仅删除其一级标题(避免与档案标题重复),
> 其余**一字未改**;本档的可判定部分以上方 8 段为准。
> 日期:2026-09-16 | 性质:**架构复盘稿**(调研 + 推演,未接入任何机器)
> 承接:`覆盖网络_百台规模推演_20260916.md`(v2)· `覆盖网络_骨干层方案_20260916.md`
> 用户要求:**覆盖全球、用户之间互联互通**的完整架构;**重点:避免网络流量风暴 + 有效组织流量上传与接收**
---
## 0. 判定与目标
✅ **有完整可循的工程路径** —— 这套东西在 Tailscale / ZeroTier / Nebula / libp2p / BitTorrent 上已被反复验证,**关键是照抄它们踩过的坑,而不是自己发明**。
**目标形态**:任何用户在任何网络(服务器 / 家宽 / 共享 IP / 移动网 / 企业网 / VPN)里的设备,都能与自己的其他设备、以及授权的他人设备互通;**全球可接入**,且**网络在规模化时不产生风暴**。
> 🟢 **范围声明(2026-09-16 用户定)**:**本方案只考虑技术实现;跨境数据合规由使用者自行考虑。**
> 因此:① 技术选型**不为合规让路** —— 多区域就近部署是**性能**最优的结果,不是合规动作;② 跨境**不设限**(不做地域封禁、不做数据落地/留存约束);③ **后续读者 ⛔ 不要再把合规 / 数据主权 / 备案当作本方案的前置条件、约束或上抛项**。
---
## 1. 架构分层(五层)
| 层 | 职责 | 关键要求 |
|---|---|---|
| **控制面** | 身份、授权、归属/租约、网络地图(netmap)分发 | **承载几乎零流量**;**挂了不影响已建立的数据面**(节点内存缓存状态) |
| **会合层** | 交换候选地址、协助打洞、签发骨干目录 | 多区域、多实例、可缓存 |
| **骨干 / 中继层** | 打洞失败时转发密文;可选做区域汇聚 | **限额资源**(预约制 + TTL + 配额),**不可无限使用** |
| **数据面** | 端到端加密的节点间直连/中继传输 | 直连优先;**空闲不建连**;扇出设上限 |
| **观测层** | 路径类型(直连/中继)、时延、重连次数、带宽 | 没有它,容量规划与排障只能靠猜 |
**全球布局要点**:会合与中继按区域就近部署(业内做法:DERP 覆盖 **20+ 区域**,每区域多台冗余);跨洲回源要显式避免。
---
## 2. 必须内建的特性清单(12 条)
1. **控制面 / 数据面彻底分离** —— 业内实测:控制面挂掉时,节点用内存里的网络地图**继续跑**,已有连接不断。
2. **连接总是"先中继、再升级直连"** —— 先保证能连上,再后台升级到直连(Tailscale 的路径:**直连 → 自有中继 → 共享中继**)。
3. **直连成功率要作为一等指标** —— 业内 >90–94%(UDP 打洞成功率约 94%),**自有节点做中继**时实测 **延迟降 ~150 ms、吞吐提升 12.5×**。
4. **空闲不建连(懒建连)** —— WireGuard 对空闲 peer **不握手、不维护状态**:拓扑是"潜在可达",不是"常连"。
5. **中继是稀缺资源,要准入** —— 限额中继协议(预约 + TTL + 单次最大时长/数据量)是标准做法。
6. **失败要能"判死"** —— 判定"不可打洞的节点"直接降级中继,**不要反复重试**。
7. **端到端加密 + 中继不解密** —— 中继只见元数据(谁连谁、量多大)。
8. **一机一身份 + 可吊销**(现有共享密钥不满足)。
9. **自报网络画像** —— 路径类型 / NAT 类型 / 是否 VPN / 上行带宽。
10. **内容寻址 + 分级缓存** —— 同一份静态资源全网只取一次。
11. **统一限流与退避参数表**(下一节的"预算表")。
12. **可见性默认最小**(接入 ≠ 可见)。
---
## 3. 技术选型对照(照抄成熟做法)
| 维度 | 成熟做法 | 出处 |
|---|---|---|
| 隧道 | WireGuard(内核态或用户态) | Tailscale / NetBird |
| 打洞 | STUN + 同时发包;**先经中继交换信息再升级直连** | Tailscale DERP / libp2p **DCUtR** |
| 中继 | 限量中继(预约 + TTL + 配额);自有节点可当专用中继 | libp2p **relay v2** / Tailscale **Peer Relays** |
| 兜底通道 | **HTTPS/443**(UDP 全被封时仍能通) | DERP over TLS 443 |
| 连接管理 | 低/高水位 + **宽限期** + 按连接价值衰减裁剪 | libp2p Connection Manager(100 / 400 / 1 min) |
| 拨号限流 | **每对端最多 4 个并发拨号**、总并发 100、超时 30 s | libp2p Dialer 默认值 |
| 资源上限 | 连接数 / 流数 / 每协议流数 / 内存上限 + 自动伸缩 | libp2p Resource Manager |
| 中继自荐节流 | 服务广告**延迟 15 min、TTL 30 min** | libp2p HOP relay advertise |
| 中继数量上限 | 每节点最多预约 **2** 个中继 | libp2p `autoRelay.maxListeners` |
| 上传调度 | **同时上传对象上限 4**、10 s 重评、**30 s 随机试新对端** | BitTorrent choking |
| 分发调度 | **稀有优先**(+ 新人先随机易得)、末段加速、哈希校验 + 封禁 | BitTorrent |
---
## 4. ⚡ 流量风暴类型学(**重点一**)
> 每一类都给出:成因 → 触发 → 处置。**风暴的本质是"放大"**:一个事件被 N 个节点同时响应,就被放大了 N 倍。
| # | 风暴 | 成因 | 典型触发 | 处置 |
|---|---|---|---|---|
| 1 | **冷启动拉取风暴**(flashcrowd) | 大量节点同时拉同一份大资源 | 新版本发布(100 台 × 10.8 MB = **1.08 GB**) | 内容寻址 + 分级缓存 + **错峰启动** + 令牌桶 + 拉取而非推送 |
| 2 | **重连风暴 / 惊群** | 控制面或中继抖动 ⇒ 全体同时重连 | 控制面重启、中继切换 | **指数退避 + 随机抖动**;数据面不依赖控制面存活 |
| 3 | **保活风暴(N²)** | 全互联逐对保活 | 节点数增长(100 台全互联 = 4,950 对) | **禁全互联**;懒建连;**按需激活**;保活预算表 |
| 4 | **重试 / 重传风暴** | 打洞反复失败仍重试 | 对称 NAT / CGNAT 节点 | **失败预算**(每对端并发拨号 ≤4)+ 退避 + **判定即降级中继** |
| 5 | **同步 / 对账风暴** | 全量状态对账 | 状态变更或周期任务 | 增量 + 摘要比对 + 周期错峰 + 限速 |
| 6 | **探测风暴** | 每节点探测全部对端 | 监控过密 | 抽样探测 + 只在有流量时探测 + 结果缓存 |
| 7 | **NAT 表溢出** | 同 NAT 后多台同时向同一目标打洞 | 同一办公室多台设备 | **每 NAT / 每子网打洞并发上限** + 分散端口 |
| 8 | **中继过载 → 抖动放大** | 中继打满 ⇒ 超时 ⇒ 重试 ⇒ 更堵 | 突发流量 | 中继侧**准入 + 背压**;**超时不要立刻重试**;预约制配额 |
| 9 | **广播 / 泛洪风暴** | L2 广播或 gossip 无上限扩散 | 错误的二层拓扑 / 无 fanout 限制 | 覆盖层坚持 **L3**;gossip **限制扇出**或改拉取式 |
| 10 | **元数据 / 目录风暴** | 所有节点同时拉目录与 ACL | 目录更新 | 签名目录 + **TTL 缓存** + 多镜像 + 不推送 |
### 4.1 三条治风暴的总原则
1. **放大点前置** —— 任何"会被 N 个节点同时响应"的事件,都要在第一跳就被**限流 + 错峰 + 缓存**。
2. **失败不要变成重试** —— 重试是风暴的最大推手;必须"退避 + 抖动 + 判死"。
3. **数据面与控制面解耦** —— 控制面抖动不该引起数据面重连;否则一次发布 = 一次全局风暴。
---
## 5. 📊 流量的组织:上传与接收(**重点二**)
### 5.1 五条原则
1. **拉优先于推**:所有"广播"改为带 TTL 的本地缓存轮询 —— 服务器主动推 N 份 = 天然的放大。
2. **懒建连 + 按需激活**:连接由"有数据要发"驱动,不由"拓扑完整"驱动(WireGuard 对空闲 peer 零状态是这条的现成地基)。
3. **限制扇出**:任何节点**同时上传/转发的对象数设硬上限**(BitTorrent 是 4),否则上行带宽被稀释。
4. **直连优先、中继兜底且中继准入**:中继是稀缺资源,用预约 + TTL + 配额管住。
5. **内容寻址 + 分级缓存**:同一份 bundle 全网只该被取一次(把 100×10.8 MB 压成 1 份 + 99 次命中)。
### 5.2 流量预算表(什么频率、多大、放大后多少、用什么管住)
| 流量 | 频率 | 单次 | 100 台放大 | 上限手段 |
|---|---|---|---|---|
| 控制面心跳 | 20 s | ~100 B | **5 req/s**(可忽略) | 懒心跳(有变化才发)+ 合并上报 |
| 归属 / 状态同步 | 事件驱动 | 小 | 低 | 增量 + **单点写** |
| 打洞尝试 | 建连时 | 小 | 受并发约束 | **每对端 ≤4 并发** + 每 NAT 上限 |
| **客户端 bundle 首屏** | 版本变化时 | **10.8 MB** | **1.08 GB** | **内容寻址 + 边缘/本地缓存 + 局域网共享**;已加载走 **304** |
| 工作区文件传输 | 用户驱动 | 可变 | 不可预测 | 分片 + 断点续传 + 背压 + 后台限速 |
| 版本 / 目录分发 | 发布时 | 大 | 爆炸 | **分层拉取**(骨干 → 区域 → 边缘 → 节点),不推送 |
### 5.3 借鉴 BitTorrent 的调度(可直接搬的四件事)
| 机制 | 作用 | 对我们的用途 |
|---|---|---|
| **同时上传上限(4)** | 防止带宽稀释,逼出互惠 | 节点/中继的并发上传上限 |
| **随机试新对端(30 s)** | 跳出局部最优;让新人拿到第一份数据 | 新节点快速进入"可交换"状态 |
| **稀有优先** | 让资源分布**均匀化** ⇒ 最大化并发可交换性 | 大文件/多副本资源的分片调度 |
| **校验 + 封禁** | 防恶意节点反复喂坏数据浪费带宽 | 客户端版本包与资源包的完整性 |
⚠️ 一条已实测的坑(学术结论):**单纯按速率互惠对低带宽节点不公平**(高带宽节点上传量可达下载量的 7 倍);改为**配对块级记账**(`已上传 ≤ 已下载 + Δ`)能显著改善公平性且不损失利用率。
### 5.4 针对我们那份 10.8 MB 首屏的专项处置
1. **内容寻址 + 不可变缓存**:版本号即内容指纹 ⇒ 可以永久缓存、跨节点复用。
2. **分级缓存**:区域边缘缓存一份,局域网内**互相共享**(办公室/家庭多台设备只回源一次)。
3. **已加载走 304**(平台已有此能力)。
4. **错峰 + 令牌桶**:版本发布时不要 100 台同时拉。
5. ⇒ 把"跨机冷加载 10.8 MB"从**常态**降成**例外**。
---
## 6. 全球规模的额外约束
| 约束 | 影响 | 处置 |
|---|---|---|
| **RTT 与带宽时延积** | 跨洲 RTT 200 ms,单条 TCP 吞吐受窗口限制 | 调大窗口 / 用 QUIC 多流;避免跨洲回源 |
| **区域就近** | 跨区域中继 = 白付延迟与带宽 | GeoDNS / anycast 落地会合与中继 |
| ~~数据主权与合规~~ | **不在本方案范围**(见 §0 范围声明) | 由使用者自行考虑 —— 技术上不做地域封禁、不做数据落地约束 |
| **时钟** | 签名 / 证书校验依赖时间 | 强制时间同步 + 容忍窗口 |
| **观测** | 全球分布后本地排障失效 | 集中指标 + 每节点自报画像 |
---
## 7. 与现平台的结合点
| 项 | 判定 |
|---|---|
| 归属 / 租约 / 资格签发 | ⛔ **必须单点控制面**(现架构已如此,继续沿用) |
| 会合 / 中继多实例 | ✅ 属数据面,**架构本来就允许** |
| 客户端形态 | ✅ 单机自用 + 覆盖网络互联**不矛盾**(租户维度收窄 ≠ 网络维度收窄) |
| 现有中继 | ⚠️ 现在是**绑在 Manager 上的 SSH 反向隧道(单中心)** ⇒ **必须先拆成可独立部署组件** |
| 现有 20 s 心跳 | ✅ 正好落在 NAT 老化的安全区间内 |
| 共享密钥 | ❌ 必须换成一机一钥 + 可吊销 |
| 11 MB bundle + ETag/304 | ✅ 已有基础,需补**内容寻址与分级缓存** |
---
## 8. 落地顺序
1. 拆出**会合 / 中继**为独立组件(脱离 Manager)。
2. 换传输:SSH 隧道 → **单进程多对端**隧道(内存差 1–2 个数量级)。
3. 身份:一机一钥 + 吊销 + 自报网络画像。
4. 补 **443/TCP 兜底**通道(治封 UDP 的企业网/校园网)。
5. 上**限流与退避参数表**(§5.2)+ 连接水位/宽限期/扇出上限。
6. 内容寻址 + 分级缓存(治 10.8 MB 首屏)。
7. 骨干层(多中心 + 选择性加入,见骨干层方案);观测与容量告警。
---
## 9. 未验证项(勿当结论)
| # | 项 | 状态 |
|---|---|---|
| 1 | 各网络类型实际占比 | ⚠️ 推演设定(决定中继容量) |
| 2 | 本环境实测打洞成功率 | ⚠️ 未实测(业内 90–94% 只能作参考) |
| 3 | 自有中继的性能收益(延迟/吞吐) | 📋 业内实测 −150 ms / 12.5×,**本环境未复现** |
| 4 | 中继出口带宽与链路质量 | ⚠️ 未实测(跨云 22 KB/s 只能作下界) |
| 5 | 控制面机规格 | ⚠️ 旧记录 1.8 GB / 2 核,**待复核** |
| 6 | ~~跨境传输合规口径~~ | ⏹ **已出范围**(2026-09-16 用户:「方案只考虑技术实现,跨境数据合规是谁用谁自己考虑」)—— **不再作为方案约束或上抛项** |
@@ -0,0 +1,253 @@
# 105 · 覆盖网络 · 骨干层方案
- 日期:2026-09-16 | 状态:📋 **规划态 / 未实施**(设计稿;未接入任何机器)
- 来源:工作区根 `覆盖网络_骨干层方案_20260916.md`(正文见 附录 A)
- 层级:专项设计(承接档案 **106** §7 P0-1 的展开)|关联:档案 104 §7 落地顺序第 7 步
- 触发(用户原话):**有公网 IP 的节点是否可以设置专门的网络服务,让其他有公网 IP 的节点加入形成专门的覆盖网络,其他用户节点可以选择性加入**
> **TL;DR**
> ✅ **可以,而且是成熟系统里的标准模式** —— 业内叫「**超级节点 / 骨干层(supernode / backbone)**」(ZeroTier Moon · Nebula Lighthouse · Tailscale DERP · libp2p AutoRelay · 早期 Skype supernode)。
> 它解决的正是推演里最贵的那条:**中继容量要按 45–55% 的 L3 占比预留**,靠一台中心服务器扛不住 —— 而网络里本来就躺着现成的公网出口。
> 🔑 三条硬约束:**接入 / 成员 / 可见三分离**;**骨干资格只能控制面签发**;**骨干不得被默认征用**。
## 一、目标
把「有公网 IP 的节点组成骨干层、其他节点选择性加入」设计成可落地方案。可判定「做完了没有」= 形态(多中心)· 成员上限 · 三条硬约束 · 容量数字 · 兼容性判定 · 落地 5 步 齐备。
## 二、只读前置
| # | 事实 | 核对方式(期望输出) |
|---|---|---|
| 1 | 骨干 = **一种新的 host 类型**,与 T08 host/lease 模型兼容(属新增能力标签) | 读 `src/db/`(lease)与集群化设计 §1.3 |
| 2 | 会合 / 中继**属数据面,架构本来允许多实例**;**归属/租约/资格必须单点控制面** | 集群化设计 §1.3 |
| 3 | 现有中继实现 = **挂在 Manager 上的 SSH 反向隧道(单中心)** ⇒ 落地第一步就是拆组件 | `sed -n '147,155p' src/worker/tunnel.ts` |
| 4 | 打包与分发可复用桌面客户端独立仓库的打包/更新链 | 见 `dsh桌面客户端_开发方案_20260916.md` §3.4/§6 |
| 5 | 骨干全靠**用户态 UDP/TCP**,**不需要特权** | 本档 §1 表「骨干承担」行 |
## 三、范围
- **改什么**:⏳ 未开跑。方案面 = ① 拆会合/中继为独立可部署组件 ② 控制面签发骨干资格 + 下发**签名目录** ③ 骨干互认心跳(≤10 成员全互联)④ 接入选路(主/备,秒级迁移)⑤ 接入与可见解耦 ⑥ 可选「贡献带宽给全网」开关。
- **不动什么**:⛔ 权威状态(归属 / 租约 / 资格)**不得由骨干自行批准**|⛔ 本轮不动服务器、不改代码。
- **红线约束**:R5(骨干若默认替全网转发 = **扩大权限面 + 占用他人资源**,命中 R5 与边界外 ⇒ 必须显式开关)。
## 四、决策点
**已定**
1. **形态 = 多中心骨干**(取代单中心星型):骨干成员上限 **≤10–20**(10 个 = 45 条;20 个 = 190 条;50 个 = 1,225 条)。
2. **普通节点每台只连 1–2 个骨干**(主用 + 备用)⇒ 100 台 = 100–200 条常连,完全可控。
3. **资格只能由控制面签发**(不得由骨干节点自行批准,否则出现第二个权威源、骨干沦为公网跳板)。
**待拍板(唯一一项,真取舍 —— 与档案 104 §四 同一项)**
**骨干节点的服务范围**:
- **A · 只服务自己名下的设备(自用骨干)**
优点:无合规与计费问题;不占用他人资源;**权限面不变(不命中 R5)**;实现最简单,节点只认自己的主人。
缺点:骨干数量受限于「有几个用户有公网 IP 的机器」;跨用户无法互相兜底,冗余度低。
- **B · 服务全网(共享骨干)**
优点:骨干多、冗余好、可用性高;单个骨干挂了影响小;对 L3 那 40–55 台的中继容量最容易满足。
缺点:**他人的流量跑在你的机器上**(资源与计费要立规矩);骨干会看到流量元数据(谁连谁、流量大小);节点被攻破的影响面变大。
**倾向 A→B 渐进**:先把骨干做成「自用骨干」跑通(零合规风险、可立刻验证),把「是否贡献带宽给全网」做成**显式开关**,等 A 稳了再逐个放开。
## 五、步骤(§8 落地顺序;每步自带一次验证)
1. **把会合 / 中继从 Manager 里拆出来**,做成可独立部署的组件 → 验证:Manager 重启不影响骨干侧已有转发。
2. **控制面签发骨干资格 + 下发签名目录**(骨干之间只校验,不自行批准)→ 验证:未签发的公网 IP 无法成为骨干。
3. **骨干互认与心跳**(≤10 个成员,全互联)→ 验证:45 条常连心跳 ≈ 2.3 req/s(可忽略)。
4. **接入选路**(节点就近选主/备骨干,支持秒级迁移)→ 验证:掐掉主骨干,节点秒级迁到备用。
5. **接入与可见解耦**(默认只见自己名下设备)→ 验证:借骨干转发时**不暴露对端清单**。
6. 可选:开放「贡献带宽给全网」开关(= §四 的 B 档)。
## 六、验收
| # | 口径 | 期望 |
|---|---|---|
| A | 骨干规模与常连数 | 10 个骨干 ⇒ 骨干内 **45** 条常连;每骨干接入 10–20 个节点 |
| B | 中继容量摊开 | 稳态 20–27 Mbps 摊到**多个**骨干,而非一台 |
| C | 单点故障收敛 | 骨干挂 1 个 ⇒ 受影响 = 接入它的 10–20 台,**秒级迁到备用**(不是全网掉线) |
| D | 目录可用性 | 骨干目录不可达时**用本地缓存的签名目录**继续选路(目录不能是单点) |
| E | 故障影响面 | 骨干被攻破 ⇒ 影响面 = 接入它的那批节点(**不是全网**) |
| F | 未验证项透明 | §九 四条已列全(网络类型占比、家宽上行是否够、全互联收敛开销、SSH 隧道改造工作量) |
## 七、回滚
- **本档自身**:零改动 ⇒ 无回滚需要。
- **执行期**:5 步各自独立可回滚 —— 拆组件(回退到 Manager 内置隧道)|签发资格(停发即回到无骨干态)|互认心跳(关服务)|选路(回落到单骨干)|解耦(关开关)。
- ⛔ **不可回滚项**:控制面签发资格这一条是**红线**(一旦下放给骨干自行批准即产生第二权威源)—— 不是开关。
## 八、回报格式
执行会话回填:① 每步验证命令 + 实际输出 ② 骨干清单与上限实际取值 ③ 服务范围决策落地形态(A / A→B / B) ④ 红线遵守声明(R5 未默认征用他人带宽 / 资格由控制面签发) ⑤ commit ⑥ 未完成项与卡点。
## 九、未验证项(勿当结论)
各网络类型实际占比(决定骨干数量需求,**推演设定**)|骨干节点上行带宽是否够(**家宽上行常远小于下行,未实测**)|骨干全互联在 ≤10 成员时的实际收敛开销(量级推算 2.3 req/s)|现有 SSH 隧道改造为独立组件的具体工作量(**待评估,未读该模块全量代码**)。
---
## 附录 A · 原始规划正文(逐字保留 · 2026-09-16)
> 以下为工作区根 `覆盖网络_骨干层方案_20260916.md` 的**原文全文**,仅删除其一级标题(避免与档案标题重复),
> 其余**一字未改**;本档的可判定部分以上方 8 段为准。
> 日期:2026-09-16 | 性质:**设计稿**(承接 `覆盖网络_百台规模推演_20260916.md` **P0-1** 的展开)
> 用户提出:**有公网 IP 的节点是否可以设置专门的网络服务,让其他有公网 IP 的节点加入形成专门的覆盖网络,其他用户节点可以选择性加入**
> 🟢 **范围**:**只考虑技术实现,跨境数据合规由使用者自行考虑**(同 `覆盖网络_全球架构复盘_20260916.md` §0 范围声明)
---
## 0. 判定
✅ **可以,而且这是成熟系统里的标准模式** —— 业内叫「**超级节点 / 骨干层(supernode / backbone)**」,不是新造东西。
| 先例 | 骨干层是什么 |
|---|---|
| ZeroTier | Planet(官方根)+ **Moon(自建公网节点)** |
| Nebula | **Lighthouse**(有公网 IP 的会合点,可多台冗余) |
| Tailscale | **DERP 中继** + exit node / subnet router("提供服务的节点") |
| libp2p | **relay v2 + AutoRelay**(有公网 IP 的节点自动成为中继候选) |
| 早期 Skype | **supernode**(有公网 IP 的节点自动升格) |
| EasyTier / 自建方案 | 指定"公网节点"作为中继与路由 |
**它解决的正是推演 v2 里最贵的那条**:中继容量要按 45%–55% 的 L3 占比预留 —— 靠一台中心服务器扛不住,而网络里本来就躺着现成的公网出口。
---
## 1. 形态:**多中心骨干**(取代单中心星型)
```
┌──────── 骨干层(有公网 IP,互相可直接连)────────┐
│ S1 ── S2 ── S3 ── … ── Sn (全互联或有界互联) │
└───┬──────┬──────┬───────────────┬───────────────┘
│ │ │ │ ← 选择性加入
┌─────┴─┐ ┌──┴───┐ ┌┴────┐ ┌────┴───┐
│家宽节点│ │移动网 │ │企业网│ │ VPN 节点│ ← L2/L3 层节点
└───────┘ └──────┘ └─────┘ └────────┘
```
| 项 | 取值 | 理由 |
|---|---|---|
| 骨干成员 | **有公网 IP 的节点**(服务器 / 专属 IP) | 互相可直接连,无需打洞 |
| 骨干互联 | **全互联,但成员数设上限** | 10 个 = 45 条;20 个 = 190 条;50 个 = 1,225 条 ⇒ **建议 ≤10–20** |
| 普通节点接入 | 每台只连 **1–2 个骨干**(主用 + 备用) | 100 台 ⇒ 100–200 条常连,完全可控 |
| 骨干承担 | 会合(rendezvous)· 中继(relay)· 可选 STUN-like 探测 | 都是用户态 UDP/TCP,**不需要特权** |
---
## 2. 一个骨干节点要跑什么(可以打成一个独立组件)
| 服务 | 作用 | 流量特征 |
|---|---|---|
| **会合** | 把两个节点的候选地址互相告诉对方 | 极小 |
| **中继** | 打洞失败时转发密文 | **大**(按 L3 占比算) |
| **NAT 探测** | 帮节点判断自己的映射类型 | 极小 |
| **目录镜像**(可选) | 分发"有哪些骨干可用"的**签名目录** | 小 |
⇒ 这四样打包成一个「节点服务」,**正好可以放进桌面客户端那个独立仓库**(复用打包与更新链),不需要碰平台主进程。
---
## 3. 三条必须钉住的设计约束
### 3.1 「选择性加入」必须拆成三个独立概念(否则一定出事)
| 层 | 含义 | 归属 |
|---|---|---|
| **接入**(connectivity) | 我能通过谁到达别人 | 节点自选(就近 / 按容量) |
| **成员**(membership) | 我在不在网里、谁批准 | **控制面签发 + 可吊销** |
| **可见**(visibility) | 我能看到/访问谁 | **ACL,默认最小** |
⚠️ **最危险的默认**是"加入骨干 ⇒ 能看见骨干上所有人"。那会变成一张巨型扁平网,与项目"**权限只准收窄**"直接冲突。
⇒ **接入与可见必须解耦**:可以借骨干做**转发通道**,而不暴露对端清单。
### 3.2 骨干资格:**只能由控制面签发**(不得由骨干节点自行批准)
- 若骨干节点能自行批准新成员 ⇒ 出现**第二个权威源**(违反单一来源),且**任何人开个公网 IP 就能进骨干** ⇒ 骨干沦为公网跳板。
- 正确形状:**控制面签发骨干成员资格(可吊销)+ 骨干之间只做"校验签名"**,不自行决策。
- 与平台既有分层判据完全一致:**会合/中继可以多实例(数据面),权威状态必须单点**。
### 3.3 骨干节点**不能**被默认征用去转发别人的流量
- 骨干节点的带宽可能属于**贡献者本人**。若默认"为全网转发" ⇒ **扩大权限面 + 占用他人资源**(命中 R5 与边界外)。
- ⇒ 必须显式:**服务范围**(只服务自己名下设备 / 服务全网)+ **带宽上限** + **随时退出**。
- 这一条需要用户定,见 §7。
---
## 4. 容量与数字(沿用推演 v2 的分层口径)
| 项 | 取值 |
|---|---|
| 100 台构成 | L1 有公网 IP **10** | L2 可打洞 **30** | **L3 只能中继 40–55** |
| 骨干规模 | 10 个 ⇒ 骨干内 **45** 条常连 |
| 每骨干接入 | **10–20** 个节点(100 / 10 上限) |
| 骨干心跳 | 45 条 × 1/20 s ≈ **2.3 req/s** ⇒ 可忽略 |
| 中继稳态 | 20–27 Mbps 总量,**摊到多个骨干**而非一台 |
| 骨干挂 1 个 | 受影响 = 接入它的那 10–20 台 ⇒ **秒级迁到备用骨干**(不是全网掉线) |
⇒ 相对单中心,**多中心骨干把"中继带宽"与"单点故障"同时摊开了** —— 这是它最大的收益。
---
## 5. 故障与运维面
| 场景 | 期望行为 |
|---|---|
| 骨干 S2 挂 | 接入它的节点秒级迁到备用骨干;正在进行的连接会断一下 |
| 骨干目录不可达 | **用本地缓存的签名目录**继续选路(目录不能是单点) |
| 骨干被攻破 | 影响面 = 接入它的那批节点(**不是全网**)⇒ 优于单中心 |
| 骨干换 IP / 身份轮换 | 由控制面更新目录,节点热切换 |
| 节点从骨干 A 迁到 B | 新旧路径短暂并存,避免"先断后连"的可见中断 |
---
## 6. 与现平台架构的兼容性(**这是能不能落地的前提**)
| 项 | 判定 |
|---|---|
| 骨干 = 一种新的 **host 类型**(有公网 IP、可做中继) | ✅ 与 T08 的 host / lease 模型兼容,属**新增能力标签** |
| 会合 / 中继多实例 | ✅ 属数据面,**架构本来就允许多实例** |
| 归属 / 租约 / 骨干资格 | ⛔ **必须单点控制面** —— 客户端与骨干一律不得持有权威状态 |
| 现有中继实现 | ⚠️ 现在是**挂在 Manager 上的 SSH 反向隧道**(单中心)⇒ 落地第一步就是**把它拆成可独立部署的组件** |
| 打包与分发 | ✅ 复用桌面客户端独立仓库的打包/更新链 |
---
## 7. 需用户拍板的一项(真取舍)
**骨干节点的服务范围**:是只服务自己名下的设备,还是替全网(含其他用户)转发流量。
**A · 只服务自己名下的设备(自用骨干)**
优点:无合规与计费问题;不占用他人资源;权限面不变(不命中 R5);实现最简单,节点只认自己的主人。
缺点:骨干数量受限于"有几个用户有公网 IP 的机器";跨用户无法互相兜底,冗余度低。
**B · 服务全网(共享骨干)**
优点:骨干多、冗余好、可用性高;单个骨干挂了影响小;对 L3 那 40–55 台的中继容量最容易满足。
缺点:**他人的流量跑在你的机器上**(资源与计费要立规矩);骨干会看到流量元数据(谁连谁、流量大小);节点被攻破的影响面变大。
**我倾向 A→B 渐进**:先把骨干做成"自用骨干"跑通(零合规风险、可立刻验证),把"是否贡献带宽给全网"做成**显式开关**,等 A 稳了再逐个放开。
---
## 8. 落地顺序(每步可单独回滚)
1. **把会合 / 中继从 Manager 里拆出来**,做成可独立部署的组件(当前是绑定在 Manager 上的 SSH 隧道)。
2. **控制面签发骨干资格 + 下发签名目录**(骨干之间只校验,不自行批准)。
3. **骨干互认与心跳**(≤10 个成员,全互联)。
4. **接入选路**(节点就近选主/备骨干,支持秒级迁移)。
5. **接入与可见解耦**(默认只见自己名下设备)。
6. 可选:开放"贡献带宽给全网"开关(= §7 的 B 档)。
---
## 9. 未验证项
| # | 项 | 状态 |
|---|---|---|
| 1 | 各网络类型实际占比(决定骨干数量需求) | ⚠️ 推演设定 |
| 2 | 骨干节点的上行带宽是否够(家宽上行常远小于下行) | ⚠️ 未实测 |
| 3 | 骨干全互联在 ≤10 个成员时的实际收敛开销 | 📋 量级推算(2.3 req/s) |
| 4 | 现有 SSH 隧道改造为独立组件的具体工作量 | 📋 待评估(未读该模块全量代码) |
@@ -0,0 +1,254 @@
# 106 · 覆盖网络 · 百台规模推演-v2
- 日期:2026-09-16 | 版本:**v2**(09:3x 按用户纠正重写前提与结论)| 状态:📋 **规划态**(**纯文字推演**,纸面演算,未接入任何机器)
- 来源:工作区根 `覆盖网络_百台规模推演_20260916.md`(正文见 附录 A)
- 层级:规模推演(第一版)| 承接档案 103 §六;上级 = 档案 104;被 105(P0-1 展开)· 107(扩到 1000 台)承接
> ⚠️ **本档含一次前提级纠错(v1 作废),务必先读 §0 修正声明**
> 用户纠正原话:**「单机用也要互联,这正是建立覆盖网络的目的」**,且 **100 台是各种网络情况,不是全都是单机**。
> v1 错在**把「租户维度收窄」误当成「网络维度收窄」**(平台只有我一个用户 ≠ 我只有一台机器、不需要跨机)。
> **TL;DR(v2)**
> 租户维度只有一个人,**不影响**网络维度有 100 台设备要互通 ⇒ **覆盖网络正是为「同一个人/团队的多台设备散落在各种网络里」而存在**。
> 异构网络最直接的后果:**中继占比远高于同构假设**(不是 15%,基准 **40–45%**、最坏 **55%**)⇒ 中继容量必须按最坏情况预留,
> 并**先把网络里现成的公网节点(L1)用起来当会合/中继**。拓扑不用换(仍是星型/分组星型),要换的是**三件**:传输、身份、**443/TCP 兜底**。
## 一、目标
对「**同一个人/团队名下 100 台异构设备**经覆盖网络互联」做纸面推演:节点画像 · 中继容量 · 拓扑 · 分场景判读 · 瓶颈排序 · P0/P1/P2 前置项。
可判定「做完了没有」= 上述六项齐备,且**每条数值都标注是「推演设定」还是「实测锚点」**。
## 二、只读前置
| # | 事实(实测锚点,非推演) | 核对方式(期望输出) |
|---|---|---|
| 1 | 跨机访问实例 UI 首屏 **≈10.8 MB**(实测) | 抓壳页 `/plugins/` 合并脚本计字节(档案 97 同源,实测 `11,363,655 B`) |
| 2 | 跨云链路 **~22 KB/s**(下界参考) | 47↔106 实测记录(见档案 110 §三) |
| 3 | 心跳间隔 **20 s** | `src/worker/tunnel.ts` 自愈定时器 |
| 4 | 归属/租约**必须单点 Manager**;会合/中继**可多实例** | 集群化设计 §1.3 |
| 5 | 节点身份现为**共享密钥**(无法吊销单台)⇒ 一机一钥是硬前置 | `src/worker/agent.ts` 头部自陈 |
## 三、范围
- **改什么**:⏳ 未开跑。本档只输出推演与 P0/P1/P2 前置清单,不含实施。
- **不动什么**:⛔ 权威状态单点语义|⛔ 本轮不动服务器、不改代码。
- **前提口径(用户纠正后)**:100 台 = **异构**(服务器 / 家宽 / 共享 IP·CGNAT / 移动网 / 企业校园网 / VPN 全隧道),**不是同构单机**。
## 四、决策点
**已定(v2 重写后的口径)**
1. **单机自用 ≠ 不需要互联** —— **租户维度收窄 ≠ 网络维度收窄**(用户原话)。⛔ 不得再用「单机自用所以没流量要互联」当前提。
2. **中继按 45% 设计 / 55% 留余量**(乐观 30% / 基准 40–45% / 悲观 55%)—— ⛔ 不得再用同构假设的 15%。
3. **必须补 443/TCP 兜底通道**(否则封 UDP 的企业/校园网整类节点进不来)。
4. **L1(有公网 IP)自动升格为中继候选池**。
5. **拓扑仍是星型 / 分组星型 + 按需建连 + 懒保活**(⛔ 不建全互联:100 台全互联 4,950 条 vs 星型 100 条,差 49.5 倍)。
**未定 / 待复核**:控制面机规格(1.8 GB / 2 核 系 09-08 旧记录);各网络类型实际占比(推演设定,需按真实设备池校准)。
## 五、步骤(§7 前置项,按 P0/P1/P2)
**P0(不做就走不通)**
1. 中继容量按 **45–55% L3 占比**设计 + **L1 自动升格** → 验证:中继容量不随玩家/设备数漂移。
2. **443/TCP 兜底通道** → 验证:封 UDP 环境仍能接入。
3. **一机一钥 + 可吊销 + 限流** → 验证:吊销单台生效。
4. **SSH 反向隧道换成单进程多对端方案** → 验证:常驻内存下降 1–2 个数量级。
**P1(不做会出事)**:中继 ≥2 台且**与控制面分开部署** + 秒级切换|跨机大流量直连优先 + 10.8 MB 首屏就近/本地缓存|保活 ≤25 s;VPN/代理类**检测即降级中继**(不重试)|重连指数退避 + 抖动 + 控制面令牌桶。
**P2**:节点自报网络画像(路径类型 / NAT 类型 / 是否 VPN / 上行带宽)|客户端 × 平台版本兼容矩阵。
## 六、验收
| # | 口径 | 期望 |
|---|---|---|
| A | 分层数字 | L1 **10** / L2 **30** / **L3 需中继 40–55**;稳态中继 **20–27 Mbps** |
| B | 拓扑对比 | 全互联 4,950 条 vs 星型 100 条 ⇒ 明确**不建全互联** |
| C | 分场景判读 | S1–S9 逐条给出判读(含 **S4 定性从「危险」修正为「核心用例」**) |
| D | 瓶颈排序 | 7 条按「先炸顺序」排(中继带宽第一) |
| E | 未验证项透明 | §九 七条已列全 |
## 七、回滚
- **本档自身**:零改动 ⇒ 无回滚需要。
- ⚠️ **v1 的前提已被推翻**:本档**取代 v1**,⛔ 不得再引用 v1 §0 的结论("100 台没有流量要互联")。v1 全文保留在 附录 A 的 §0 修正声明中(作为错误样本)。
## 八、回报格式
执行会话回填:① 校准后的网络类型实际占比(与 §2 表对照)② 实测打洞成功率(分层)③ 中继出口带宽与 jitter 实测 ④ 控制面规格复核结果 ⑤ 若推翻本档任一数字,给出实测口径与取数时间。
## 九、未验证项(勿当结论)
各网络类型**实际占比**(推演设定,需按真实设备池校准)|打洞成功率(分层:家宽 / CGNAT / 移动网 / 企业网,**未实测**)|**VPN 全隧道是否真的破坏打洞**(未实测,推演按"会破坏"保守处理)|企业网封 UDP 的比例(未实测)|中继出口带宽与链路质量(未实测,仅有跨云 22 KB/s 作下界)|控制面机规格(1.8 GB / 2 核,**待复核**)|单条 SSH 隧道常驻内存 3–5 MB(量级估计)。
---
## 附录 A · 原始规划正文(逐字保留 · 2026-09-16)
> 以下为工作区根 `覆盖网络_百台规模推演_20260916.md` 的**原文全文**,仅删除其一级标题(避免与档案标题重复),
> 其余**一字未改**;本档的可判定部分以上方 8 段为准。
> 日期:2026-09-16 | **版本:v2**(09:3x 按用户纠正重写前提与结论)| 性质:**纯文字推演**(纸面演算,未接入任何机器)
> 配套:`可行性评估_客户端安装与覆盖网络互联_20260916.md` §六|`dsh客户端化部署方案_20260916.md`|`dsh桌面客户端_开发方案_20260916.md`
> 📄 **本文的上一级(全球级复盘,含风暴类型学与流量组织)见 `覆盖网络_全球架构复盘_20260916.md`**
---
## 0. 修正声明(v1 的第 0 节被判定为错误)
> ⚠️ **用户纠正(2026-09-16 09:3x,原话要点)**:**「单机用也要互联,这正是建立覆盖网络的目的」**;且 **100 台是各种网络情况,不是全都是单机** —— 有服务器、有单机、有局域网、有互联网、有专属外网 IP、有共享外网 IP、有固定宽带、有移动网、有 VPN 等各种情况。
**v1 错在哪**:v1 断言"按单机自用形态,100 台之间根本没有流量要互联 ⇒ 覆盖网络无事可做"。
**错因**:把 **租户维度的收窄**(平台只有我一个用户)误当成 **网络维度的收窄**(我只有一台机器、不需要跨机)。
| 维度 | 单机自用是否收窄 | 说明 |
|---|---|---|
| **租户维度**(有几个人用) | ✅ **收窄为 1** | 形态开关决定 |
| **网络维度**(要连几台机器) | ❌ **完全不收窄** | **同一个人也有多台设备**,分布在家里宽带 / 移动网 / 公司网 / 云主机上 —— **这正是覆盖网络存在的理由** |
⇒ 修正后:**"单机自用"与"需要互联"不矛盾,而是同一条路线的两个正交面。** v2 据此重写。
---
## 1. 前提(v2)
| 项 | 取值 |
|---|---|
| 角色 | **同一个人(或同一个团队)名下的 100 台设备**,经覆盖网络互相可见 |
| 目标流量 | ① 跨机访问彼此的实例/工作区 ② 跨机文件与数据交换 ③ 平台侧的控制与调度 |
| 中心 | 控制面(会合点)+ 中继 —— **数量与落点见 §3(不再假设只有 1 台)** |
| 节点构成 | **异构**,见 §2 |
---
## 2. 节点构成:100 台的异构画像(**这是 v1 缺失的核心**)
> 台数为推演设定(可按实际调),**关键结论对比例敏感、对绝对值不敏感**。
| 类 | 场景 | 台数 | 公网可达 | NAT 行为 | 打洞前景 |
|---|---|---|---|---|---|
| A | **云服务器**(专属公网 IP) | 10 | ✅ 可直接拨入 | 无 NAT | 不需要打洞 |
| B | **家庭固定宽带** | 30 | ❌ | 多为锥形/受限锥形 | ✅ 最好 |
| C | **共享公网 IP / CGNAT**(含运营商大内网) | 20 | ❌ | 多用户共享同一出口,端口映射冲突 | ⚠️ 差 |
| D | **移动网**(4G/5G) | 15 | ❌ | **对称 NAT + CGNAT 居多** | ❌ 基本失败;且切基站就换 IP |
| E | **企业 / 校园局域网** | 15 | ❌ | 对称 NAT,**常封 UDP**,可能强制 HTTP 代理 | ❌ 差 |
| F | **VPN 用户**(全隧道) | 10 | 取决于 VPN | VPN 把流量全隧道化 ⇒ 映射被破坏 | ❌ 差 |
### 2.1 按可达性分三层(**决定谁是直连、谁是中继**)
| 层 | 定义 | 台数 | 在方案里的角色 |
|---|---|---|---|
| **L1** | 可直接拨入(有公网 IP) | **10** | **天然的会合点 / 中继候选** |
| **L2** | 能打洞(锥形类) | **30** | 直连主体,流量不过中心 |
| **L3** | **只能走中继** | **40–55**(C/D/E/F 中打洞失败的部分) | **中继容量必须按这一层算** |
> ⚠️ **v1 假设"15% 需中继",对异构网络严重偏低。**
> 保守口径:**按 45% 设计中继容量,按 55% 留余量。**(乐观 30% / 基准 40–45% / 悲观 55%)
### 2.2 三类"特殊网络"的处置要求(缺一样就有整类节点进不来)
| 情况 | 现象 | 处置 |
|---|---|---|
| **封 UDP**(企业网/校园网) | 打洞与 UDP 中继全失败 ⇒ 该类节点**完全看不见** | 必须提供 **443/TCP 兜底通道**(TLS 伪装),否则 E 类 15 台直接出局 |
| **全隧道 VPN** | 反复尝试打洞、每次失败、白白抖动 | **检测到即直接降级中继**,不要重试 |
| **移动网** | 切基站换 IP,直连秒断 | 保活更密(≤20 s)+ 重打洞要快,且**中继常驻为该类兜底** |
---
## 3. 中继容量:按最坏情况排(v1 的数字作废)
| 项 | v1(同构假设) | **v2(异构)** |
|---|---|---|
| 需中继的台数 | 15 | **40–55**(按 45 设计 / 55 留余量) |
| 稳态占用(按 0.5 Mbps/台) | 7.5 Mbps | **20–27 Mbps** |
| 跨机首屏突发(≈10.8 MB/台) | 165 MB | 同口径:**3 台同时冷加载 ≈ 32 MB;10 台 ≈ 108 MB** |
**由此得出 v2 的第一条新设计点**:
> 🔑 **让 L1 层(有公网 IP 的 10 台)自动升格为中继候选池。**
> 异构网络里本来就躺着现成的公网出口 —— 不利用它,就等于用一台小服务器去扛 40+ 台的流量。**同构假设下想不到这一条。**
⚠️ 但有一条硬边界(与平台既有分层判据一致):
- **会合点 / 中继:可以多实例**(谁有公网 IP 谁就能当);
- **权威状态(归属 / 租约):必须单点 Manager** —— 客户端节点永远不得持有权威状态,否则就是脑裂。
---
## 4. 拓扑:仍然**不能建全互联**(这条 v1 正确,保留)
全互联 = 100×99/2 = **4,950** 条;星型 = **100** 条 ⇒ 差 **49.5 倍**。
⇒ **星型 / 分组星型 + 按需建连 + 懒保活**。跨机通信由中心或直连路径承担,不靠"每对都常连"。
---
## 5. 分场景推演
| # | 场景 | 判读 |
|---|---|---|
| S1 | 逐台加入(1→10→50→100) | 心跳 0.1→0.5→2.5→**5 req/s**;控制面无压力 |
| S2 | 稳态一小时 | 控制面 5 req/s;中继常驻 **20–27 Mbps**(45 台口径) |
| S3 | **家宽笔记本换网**(家→公司) | 秒级重打洞;失败切中继。保活 ≤25 s 才不会表现为"随机断网" |
| S4 | **跨机访问对方实例 UI**(真实需求,非假设) | 首屏 **≈10.8 MB**(实测值):**直连**(30 台上行 20–50 Mbps)≈ **2–4.5 s ✅**;**走中继**(100 Mbps)≈ 1 s/台但并发即叠加 ⇒ **必须直连优先** |
| S5 | **移动网节点切基站** | IP 变 ⇒ 直连断 ⇒ 回中继;该类节点**在中继上是常态而非例外** |
| S6 | **企业网节点**(封 UDP) | 打洞全败 ⇒ 必须走 **443/TCP 兜底**;否则整类不可用 |
| S7 | **中继 A 挂掉** | 受影响的是 L3 那 45 台 → 必须秒级切 B;**控制面与中继分开部署**(合并 = 挂了全员失联) |
| S8 | 控制面重启 / 早高峰 100 台同上线 | 瞬时 **100 并发** ⇒ 指数退避 + 抖动 + 令牌桶 |
| S9 | 异常节点 | 现状是**共享密钥**(无法吊销单台)⇒ 一机一钥是硬前置 |
**S4 的定性变了**:v1 把它当"要规避的危险场景",v2 认定它是**核心用例** ⇒ 结论从"大流量绝不能过网"**修正为**:
> **大流量优先直连、中继兜底,且中继容量按几十台常驻来配**;同时把 10.8 MB 首屏做**就近/本地缓存**(同版本复用 + 已有 ETag/304),把跨机冷加载从常态降为例外。
---
## 6. 瓶颈排序(v2,按先炸顺序)
| 序 | 瓶颈 | 触发条件 | 量级 |
|---|---|---|---|
| 1 | **中继带宽** | L3 占 45%(v1 只算 15%) | 稳态 20–27 Mbps + 突发叠加 |
| 2 | **443/TCP 兜底通道缺失** | 企业网/校园网封 UDP | 整类节点(E: 15 台)完全进不来 |
| 3 | **控制面机内存** | 若沿用 SSH 隧道(每连接一进程) | 100 × 3–5 MB = **300–500 MB** |
| 4 | 控制面单点 | 重启/升级 | 100 并发重连风暴 |
| 5 | 共享密钥 | 无法吊销、可整片放行 | 一机一钥是硬前置 |
| 6 | VPN / 代理类节点 | 反复打洞失败 | 白抖动,需检测即降级 |
| 7 | 版本碎片 | 客户端 × 平台 | 排障成本随台数线性涨 |
---
## 7. 要扩到 100 台必须先做的(v2 修订)
**P0(不做就走不通)**
1. **中继容量按 45%–55% 的 L3 占比设计**,且**让有公网 IP 的节点自动成为中继候选**(不能只有一台中心)—— 具体设计见 **`覆盖网络_骨干层方案_20260916.md`**(多中心骨干 + 选择性加入 + 资格由控制面签发)。
2. **443/TCP 兜底通道**(治封 UDP 的企业网/校园网)——否则整类节点进不来。
3. **一机一钥 + 可吊销 + 限流**(替换共享密钥)。
4. **把 SSH 反向隧道换成单进程多对端方案**(内存差 1–2 个数量级)。
**P1(不做会出事)**
1. 中继 ≥2 台、就近选择、**与控制面分开部署**、秒级切换。
2. **跨机大流量直连优先** + 10.8 MB 首屏就近/本地缓存。
3. 保活 ≤25 s;VPN / 代理类节点**检测即降级中继**(不重试)。
4. 重连指数退避 + 抖动 + 控制面令牌桶。
**P2**
1. **节点自报网络画像**(路径类型 直连/中继、NAT 类型、是否在 VPN、上行带宽)——没有它,容量规划与排障只能靠猜。
2. 版本兼容矩阵(客户端 × 平台)。
---
## 8. 结论(v2,三句)
1. **单机自用与互联是两件事**:租户维度只有一个人,**不影响**网络维度有 100 台设备要互通 —— **覆盖网络正是为"同一个人/团队的多台设备散落在各种网络里"而存在的**。v1 把这两维混为一谈,是本次推演最根本的错误。
2. **异构网络最直接的后果是"中继占比远高于同构假设"**(不是 15%,基准 40–45%、最坏 55%)⇒ **中继容量必须按最坏情况预留**,并且**要先把网络里现成的公网节点用起来当会合/中继**。
3. **拓扑不用换(仍是星型/分组星型),要换的是三件**:传输(SSH → 多对端隧道)、身份(共享密钥 → 一机一钥)、**兜底通道(补 443/TCP)** —— 第三件在 v1 里完全没出现,是异构网络画像逼出来的。
---
## 9. 本推演的未验证项(勿当结论)
| # | 项 | 状态 |
|---|---|---|
| 1 | 各网络类型的**实际占比** | ⚠️ 推演设定(§2 表),需按真实设备池校准 |
| 2 | 打洞成功率(分层:家宽 / CGNAT / 移动网 / 企业网) | ⚠️ 未实测 |
| 3 | **VPN 全隧道是否真的破坏打洞** | ⚠️ 未实测(推演按"会破坏"保守处理) |
| 4 | 企业网封 UDP 的比例 | ⚠️ 未实测 |
| 5 | 中继出口带宽与链路质量 | ⚠️ 未实测(仅有跨云 22 KB/s 作为下界参考) |
| 6 | 控制面机规格(1.8 GB / 2 核) | ⚠️ 来自 2026-09-08 旧决策记录,**需复核** |
| 7 | 单条 SSH 隧道常驻内存 3–5 MB | 📋 量级估计 |
@@ -0,0 +1,289 @@
# 107 · 覆盖网络 · 千台全场景推演
- 日期:2026-09-16 | 状态:📋 **规划态**(**文字推演**;纸面演算,未接入任何机器)
- 来源:工作区根 `覆盖网络_千台全场景推演_20260916.md`(正文见 附录 A)
- 层级:规模推演(第二版 · 千台)| 承接档案 **106**(v2) · 104 · 108 · 109;被 **112**(瓶颈落地)承接
- 🟢 范围:只考虑技术实现;跨境数据合规由使用者自行考虑。
> **TL;DR**
> 1000 台异构设备 × 11 个场景的流量推演。**控制面在 1000 台规模仍不是瓶颈**(50 req/s);
> 🔥 **先炸的是 presence**(1000 人大房 ≈ **16,700 次/秒**,是其消息扇出 1,000/s 的 **16 倍**);
> 💰 **「游戏服放在哪里」是本方案最大的成本杠杆**:放有公网 IP 的节点 ⇒ 中继承载 **0**;放家宽 ⇒ **600 Mbps 常驻**。
## 一、目标
把推演从 100 台扩到 **1000 台**,给出:设备构成 × 应用构成 · 11 个分场景推演 · **流量预算总表** · 瓶颈排序 · 五条结论。
可判定「做完了没有」= 上述五项齐备,且**关键实测锚点与推算值被明确区分**。
## 二、只读前置
| # | 事实(**关键实测锚点,非推算**) | 核对方式(期望输出) |
|---|---|---|
| 1 | 实例首屏含客户端合并脚本 **11,363,655 B ≈ 10.8 MB**(含 ETag/304 短路) | 抓壳页 `/plugins/` 计字节(档案 97) |
| 2 | 跨云链路实测 **~22 KB/s** | 47↔106 实测(档案 110 §三) |
| 3 | 心跳间隔 **20 s** | `src/worker/tunnel.ts` 自愈定时器 |
| 4 | 不可再生数据 **46.3 MB** / 可重建 **2.9 GiB** | 备份口径(档案 110 §二) |
| 5 | 归属/租约单点;会合/中继可多实例 | 集群化设计 §1.3 |
## 三、范围
- **改什么**:⏳ 未开跑。本档只输出推演与瓶颈排序,**不含实施**。
- **不动什么**:⛔ 权威状态单点语义|⛔ 本轮不动服务器、不改代码。
- **推演设定**:1000 台异构(A 云 100 / B 家宽 300 / C CGNAY 200 / D 移动网 150 / E 企业校园 150 / F VPN 100);
应用 = 40 游戏服 × 300 玩家(玩家为**外部客户端,不计入这 1000 台**)+ 200 房 × 50 人 + 1 个 1000 人大房 + 2000 agent + 200 台每日增量备份。
## 四、决策点
**已定**
1. **中继容量按 48.5% 实测口径排、按 55% 预留**(区域性网络突变会让某类节点同时回中继 ⇒ 中继瞬时翻倍)。
2. **游戏服一律放有公网 IP 的节点(L1)** ⇒ 中继流量从 600 Mbps 降到 0(**收益最大的一次选择**)。
3. **一次性大流量只有两处**(首屏 10.8 GB / 次、备份 10 GB / 晚)——**都用「分级缓存 + 错峰 + 低优先级」治,不用加带宽治**。
4. **游戏的真正门槛是抖动(<20 ms),不是带宽** —— 中继链路选型要按**抖动**评估。
5. **agent 是本方案独有的放大源**,必须独立预算;**单房间实际上限 = min(扇出预算, presence 预算, agent 预算)**。
**未定**:各类设备**打洞成功率**(本推演用估值表,未实测);中继链路 jitter 是否满足 <20 ms(**决定游戏可玩性,最该先测**)。
## 五、步骤(承接本档 §4 瓶颈排序;每步自带一次验证)
1. **presence 改造**(订阅裁剪 + 批合并 + 大房降频)→ 验证:1000 人大房广播**从 ~16,700/s 降到 <2,000/s**。
2. **游戏服部署规范(放 L1)** → 验证:新开服默认落 L1;中继出口带宽与「服数」关系**可预测**。
3. **内容寻址 + 分级缓存**(治首屏 10.8 GB)→ 验证:版本发布时回源字节 ≈ 1 份 × 组数。
4. **重连治理**(指数退避 + 全抖动 + 重试预算 + 令牌桶)→ 验证:拔掉一台中继后重连曲线**平滑爬升**而非尖峰。
5. **备份抖动窗口 + 低优先级队列** → 验证:备份期间聊天与游戏 **p95 延迟不变**。
6. **jitter 度量与按抖动选路** → 验证:jitter 直方图 + 超阈值自动切路径并告警。
7. **agent 四条硬约束 + 独立配额** → 验证:注入「回声型 agent」压测,房间消息量**有上限、不增长**。
8. **每子网打洞并发上限 + 收敛探测** → 验证:同一办公室 20 台同时上线,NAT 不丢线。
9. **协议版本治理**(协商 + 灰度 + 相邻版本互通)→ 验证:各版本节点数与错误率**按版本切分**可观测。
> 📌 具体做法(含 Slack / SCCM 官方照抄点)见 **档案 112**;若只做三件:**presence + 游戏服放 L1 + 块级内容寻址**。
## 六、验收
| # | 口径 | 期望 |
|---|---|---|
| A | 流量预算总表 | 每类流量有「频率 / 单次 / 1000 台放大 / 上限手段」四列 |
| B | 瓶颈排序 | 9 条按「先炸顺序」排(presence 第一) |
| C | 杠杆数字 | 游戏服放 L1 ⇒ 中继 **0**;放家宽 ⇒ **600 Mbps 常驻**(峰值 1.2–2.0 Gbps) |
| D | 结论可判定 | 五条结论均可被第三方复算 |
| E | 未验证项透明 | §六 五条已列全 |
## 七、回滚
- **本档自身**:零改动 ⇒ 无回滚需要。
- **执行期**:§五 九步各自独立可回滚(presence 改造 / 部署规范 / 缓存 / 退避 / 队列 / 选路 / 配额 / 并发上限 / 版本治理均为独立开关或参数)。
## 八、回报格式
执行会话回填:① 每步验证命令 + 实际输出 ② 实测的打洞成功率与 jitter 分布(**与 §0.1/§6 估值表对照**) ③ presence 收敛实际降幅 ④ agent 放大系数实测 ⑤ 1000 并发重连压测结果 ⑥ commit ⑦ 未完成项与卡点。
## 九、未验证项(勿当结论)
各类设备**打洞成功率**(估值表,未实测)|中继链路 **jitter** 是否满足 <20 ms(**决定游戏可玩性,最该先测**)|presence 收敛(订阅裁剪)实际降幅(未实测,业界口径可达 5×)|agent 参与的放大系数(未实测)|1000 并发重连时控制面/中继实际表现(未压测)。
---
## 附录 A · 原始规划正文(逐字保留 · 2026-09-16)
> 以下为工作区根 `覆盖网络_千台全场景推演_20260916.md` 的**原文全文**,仅删除其一级标题(避免与档案标题重复),
> 其余**一字未改**;本档的可判定部分以上方 8 段为准。
> 日期:2026-09-16 | 性质:**文字推演**(纸面演算,未接入任何机器;数值标"实测"的除外,其余为推算)
> 承接:`覆盖网络_百台规模推演_20260916.md`(v2) · `覆盖网络_全球架构复盘_20260916.md` · `覆盖网络_游戏专项_MMORPG与MUD_20260916.md` · `覆盖网络_调研_游戏网络特征与群聊上限_20260916.md`
> 🟢 范围:只考虑技术实现;跨境数据合规由使用者自行考虑。
---
## 0. 推演设定
### 0.1 设备构成(1000 台,异构)
| 类 | 场景 | 台数 | 打洞成功率(估) | 可直连 | **需中继** |
|---|---|---|---|---|---|
| A | 云服务器(**专属公网 IP**) | 100 | 不需打洞 | 100 | 0 |
| B | 家庭固定宽带 | 300 | ~90% | 270 | 30 |
| C | 共享公网 IP / CGNAT | 200 | ~40% | 80 | 120 |
| D | 移动网(4G/5G) | 150 | ~10% | 15 | 135 |
| E | 企业 / 校园局域网(常封 UDP) | 150 | ~20% | 30 | 120 |
| F | VPN 全隧道 | 100 | ~20% | 20 | 80 |
| | **合计** | **1000** | | **515** | **485(48.5%)** |
⇒ 与"按 **45%** 设计中继容量、按 **55%** 留余量"的口径吻合。
### 0.2 应用构成(跑在这 1000 台上)
| 应用 | 规模设定 |
|---|---|
| **游戏服**(MMORPG/传奇/MUD) | **40 服**,每服 300 玩家(玩家为**外部客户端,不计入这 1000 台**) |
| **群聊房间** | 200 个房间 × 平均 50 人;**另有 1 个 1000 人大房**(压测极端) |
| **Agent** | 平均每台 2 个 ⇒ **2000 个 agent** |
| **备份** | 200 台做每日增量 |
| **迁移** | 每月数次,单次 ~46.3 MB(不可再生数据口径) |
### 0.3 关键实测锚点(非推算)
- 实例首屏含客户端合并脚本 **11,363,655 B ≈ 10.8 MB**(含 ETag/304 短路)
- 跨云链路实测 **~22 KB/s**(下界参考)
- 心跳间隔 **20 s**(沿用现有隧道自愈定时器)
---
## 1. 设备类型 × 应用 的分工矩阵
| 设备类型 | 台数 | 典型角色 | 关键约束 |
|---|---|---|---|
| **云服务器(专属 IP)** | 100 | **骨干 / 中继 / 游戏服 / 备份汇聚** | 上行按量计费 ⇒ 别当默认中继 |
| **家庭固定宽带** | 300 | 常用客户端 / **服主** / 备份目标 | **上行小(20–50 Mbps)**、IP 会变 |
| CGNAY / 共享 IP | 200 | 常用客户端 | **必走中继** |
| 移动网 | 150 | 移动端客户端 | **抖动大**、切网频繁 |
| 企业 / 校园网 | 150 | 办公客户端 | **封 UDP ⇒ 必须有 443/TCP 兜底** |
| VPN 全隧道 | 100 | 远程办公 | 打洞被破坏 ⇒ 检测即降级中继 |
---
## 2. 分场景推演
### S1 · 冷启动(1000 台加入)
| 项 | 数值 | 判读 |
|---|---|---|
| 控制面心跳(稳态) | 1000 / 20 s = **50 req/s** | 可忽略 |
| **同时上线(惊群)** | 瞬时 **1000 并发** | 必须**令牌桶**(如 10/s ⇒ 100 s 接纳完)+ 退避抖动 |
| **首屏 bundle** | 1000 × 10.8 MB = **10.8 GB** | ⚠️ **单次最大流量** ⇒ 内容寻址 + 分级缓存(区域边缘 + 局域网共享);已加载走 304 |
⇒ 冷启动的唯一大坑是 **10.8 GB 一次性拉取**,不是心跳。
### S2 · 稳态(无大任务)
| 流量 | 计算 | 结果 |
|---|---|---|
| 控制面心跳 | 1000 / 20 s | **50 req/s** |
| **presence(200 房 × 50 人)** | `200×50×49 / 60` | **≈8,200 次/秒** |
| **presence(那个 1000 人大房)** | `1000×1000 / 60` | **≈16,700 次/秒** |
| 群聊消息(全局 50 msg/s,均扇出 50) | `50×50` | 2,500 投递/秒 |
| 大房消息(1 msg/s) | `1×1000` | 1,000 投递/秒 |
> ⚠️ **本轮最重要的量化结论之一**:**presence 比消息早爆一个量级** ——
> 1000 人大房的 presence(**16,700/s**)是其消息扇出(1,000/s)的 **16 倍**;连"200 个普通房加起来"(8,200/s)都被它一个人超过。
> ⇒ **第一瓶颈是 presence,不是消息**;大房必须**单独策略**(只推在线/离线态 + 批合并 + 降频)。
### S3 · 游戏(40 服 × 300 玩家)——**"服放哪"决定中继成本差一个数量级**
| 部署方式 | 每服上行 | 中继承载 | 结论 |
|---|---|---|---|
| **服放有公网 IP 的节点(L1)** | 300 × 10 KB/s = **24 Mbps** | **0** | ✅ **玩家直连,中继完全不承载** |
| 服放家宽 / CGNAT 后(假设 40 服中 25 服) | 同上 | **25 × 24 Mbps = 600 Mbps 常驻** | ⚠️ 单台 1 Gbps 中继都不够,还要留峰值 |
- 峰值(攻城战):带宽翻倍 ⇒ 48–80 Mbps/服 ⇒ 25 服同时攻城 = **1.2–2.0 Gbps** ⇒ 必须错峰 + 配额。
- 抖动门槛:**jitter < 20 ms**,否则位置与战斗 desync ⇒ **中继路径必须按抖动评估,不能只看带宽**。
> ⭐ **结论:把游戏服放在有公网 IP 的节点上(= 骨干层),是本方案里收益最大的一次选择** —— 中继流量从 600 Mbps 直接降到 0。
### S4 · 群聊极端房(1000 人)
| 项 | 数值 |
|---|---|
| presence | **16,700 次/秒** ← 瓶颈 |
| 消息扇出(1 msg/s) | 1,000 投递/秒(可承受) |
| 必须做的 | presence 只推在线/离线 + 批合并 + 降频;消息**切游标拉取**;**慢速模式**;RBAC 缓存 |
⇒ 单房间建议上限按**扇出预算**定义,而不是人数(见调研稿 §2.4)。
### S5 · Agent 风暴(**本方案独有的放大源**)
- 2000 个 agent(平均每台 2 个)。若那个 1000 人房里聚集 200 个 agent:
- 无约束 ⇒ agent 互相激发 ⇒ 消息量**指数增长**(A 说 → B 回 → …)⇒ 房间被瞬间打满。
- 必需四条硬约束:**① 禁止 agent 直接触发 agent(只有人的消息能触发)② 每 agent 每 N 分钟最多 M 条 ③ 发言后静默期 ④ 房间级 agent 数上限**(建议 ≤ 房间人数 / 10)。
> ⇒ **对本方案而言,单房间的实际上限由「presence + agent 预算」决定**,消息扇出还在其次。
### S6 · 备份窗口(每晚 02:00)
| 口径 | 计算 | 结果 |
|---|---|---|
| 200 台 × 增量 50 MB | 10 GB | — |
| 摊到 1 小时 | 10 GB / 3600 s | **22 Mbps**(可接受) |
| **集中在头 10 分钟** | 10 GB / 600 s | **136 Mbps** ⚠️ 会挤占游戏与聊天 |
⇒ 必须**抖动窗口 + 低优先级队列**(交互流量优先)。
### S7 · 迁移(大文件)
- 单次 46.3 MB;若链路只有 22 KB/s ⇒ **35 min**(这是慢链路下界)。
- 手段:分片多流 / 先压缩 / 惰性拉取 / 经对象存储中转。
- 10 台同时迁移 ⇒ 必须配额,不能占满中继。
### S8 · 中继故障
- 中继 A 挂 ⇒ 其承载部分(假设 485 的 1/3 ≈ **160 台**)需切换。
- **160 并发重连** ⇒ 无退避就会打垮备用中继 ⇒ 必须**指数退避 + 抖动**。
- 若全网只 2 台中继:切换后单台要扛 485 台 ⇒ **必须 N+1 且有余量**,最好由 L1 节点组成中继池。
### S9 · 控制面重启
- 1000 台重连 ⇒ **1000 并发** ⇒ 令牌桶 + 退避。
- **数据面必须独立存活**(已建立的连接不受影响)—— 这是控制面/数据面分离的核心价值。
### S10 · 区域性网络突变
- 某运营商调 NAT / 某区域断网 ⇒ 整类节点同时回中继 ⇒ **中继瞬时翻倍**。
- ⇒ 中继容量必须按 **55%(而不是 48.5%)** 预留,且要能在数分钟内横向加中继。
### S11 · NAT 表溢出
- 同一企业网 / 同一家庭多台设备同时向同一目标打洞 ⇒ 该 NAT 表被打满 ⇒ 全屋(全办公室)掉线。
- ⇒ **每 NAT / 每子网打洞并发上限** + 分散端口 + 收敛探测频率。
---
## 3. 1000 台流量预算总表(**全案最重要的一张表**)
| 流量 | 频率 | 单次 | 1000 台放大 | 上限手段 |
|---|---|---|---|---|
| 控制面心跳 | 20 s | ~100 B | **50 req/s** | 懒心跳 + 合并上报 |
| **presence(普通房)** | 变化驱动 | 小 | **≈8,200 次/s** | 订阅裁剪(只推可见)+ 批合并 |
| **presence(1000 人大房)** | 变化驱动 | 小 | **≈16,700 次/s** | **只推在线态 + 降频 + 批合并** |
| 群聊消息 | 50 msg/s | 小 | 2,500 投递/s | 大房切**游标拉取** |
| **游戏流量** | 持续 | 24–80 Mbps/服 | **0(服放 L1)** / **600 Mbps(服放家宽)** | **把游戏服放到有公网 IP 的节点** |
| **首屏 bundle** | 版本发布 | 10.8 MB | **10.8 GB** | 内容寻址 + 分级缓存 + 错峰 |
| 备份 | 每晚 | 50 MB/台 | 10 GB/晚(集中时 **136 Mbps**) | 抖动窗口 + **低优先级** |
| 迁移 | 每月 | 46.3 MB/次 | 视并发 | 分片多流 + 配额 + 惰性拉取 |
| 打洞尝试 | 建连时 | 小 | 受并发上限 | **每对端 ≤4 并发** + 每 NAT 上限 |
| 更新/目录分发 | 发布时 | 大 | 爆炸 | **分层拉取**,不推送 |
---
## 4. 瓶颈排序(1000 台,按"先炸顺序")
| 序 | 瓶颈 | 量级 | 主要处置 |
|---|---|---|---|
| 1 | **presence** | 8.2k–16.7k 次/秒 | 订阅裁剪 + 批合并 + 大房降频 |
| 2 | **游戏服放家宽时的中继带宽** | **600 Mbps 常驻**、峰值 1.2–2.0 Gbps | **把游戏服放 L1 节点** + 错峰 + 配额 |
| 3 | **首屏 bundle 冷启动** | **10.8 GB 一次性** | 内容寻址 + 分级缓存 + 令牌桶 |
| 4 | **中继抖动**(游戏可玩性) | jitter 需 <20 ms | 中继链路质量选型 + 就近 |
| 5 | 备份窗口挤占 | 集中 136 Mbps | 抖动窗口 + 低优先级 |
| 6 | 中继 / 控制面故障重连 | **160 / 1000 并发** | 退避 + 抖动 + N+1 |
| 7 | **agent 自激** | 指数级(本方案独有) | 四条硬约束 + 房间 agent 上限 |
| 8 | NAT 表溢出 | 整屋/整办公室掉线 | 每子网打洞并发上限 |
| 9 | 版本碎片 | 排障成本 | 协议版本协商 + 灰度 |
---
## 5. 推演结论(五条)
1. **控制面在 1000 台规模仍不是瓶颈**(50 req/s);**先炸的是 presence**(16.7k 次/秒),它比消息扇出早爆一个量级。
2. **"游戏服放在哪里"是本方案最大的成本杠杆**:放有公网 IP 的节点 ⇒ 中继承载 **0**;放家宽 ⇒ **600 Mbps 常驻**。⇒ 应把骨干层与游戏服合并设计。
3. **一次性大流量只有两处**:首屏 bundle(10.8 GB/次)与备份(10 GB/晚)——**都用"分级缓存 + 错峰 + 低优先级"治,不用加带宽治**。
4. **游戏的真正门槛是抖动(<20 ms),不是带宽** —— 中继链路选型要按抖动评估。
5. **agent 是本方案独有的放大源**,必须独立预算;**单房间实际上限 = min(扇出预算, presence 预算, agent 预算)**。
---
## 6. 未验证项(勿当结论)
| # | 项 | 状态 |
|---|---|---|
| 1 | 各类设备的**打洞成功率**(本推演用的是估值表) | ⚠️ 未实测 |
| 2 | 中继链路 **jitter** 是否满足 <20 ms | ⚠️ **决定游戏可玩性,最该先测** |
| 3 | presence 收敛(订阅裁剪)的实际降幅 | ⚠️ 未实测(业界口径可达 5×) |
| 4 | agent 参与的放大系数 | ⚠️ 未实测 |
| 5 | 1000 并发重连时控制面 / 中继的实际表现 | ⚠️ 未压测 |
@@ -0,0 +1,230 @@
# 108 · 覆盖网络 · 游戏专项-MMORPG与MUD
- 日期:2026-09-16 | 状态:📋 **规划态 / 未实施**(专项设计稿)
- 来源:工作区根 `覆盖网络_游戏专项_MMORPG与MUD_20260916.md`(正文见 附录 A)
- 层级:专项设计| 承接档案 **111 §一**(其修正点);配套 **109**(游戏网络参数与群聊上限)
- 🟢 范围:只考虑技术实现;跨境数据合规由使用者自行考虑。
> ⚠️ **本档含一次判定修正**:此前按 **3D 大世界强实时竞技**评估,结论是"不合适";
> 用户明确重点是 **MMORPG(2D/2.5D)· MUD · 传奇类** —— 这三类**恰好是覆盖网络最匹配的应用**,甚至比群聊更契合。
> **TL;DR**
> 这三类游戏的架构(**服务端权威 + tick 驱动 + AOI 九宫格广播 + 分区/分线**)**本身就是覆盖网络友好型的**,
> 不需要为它改造什么,只需提供「到达游戏服的可靠低延迟路径」。
> ⭐ **最重要的简化:玩家之间不需要互联**(服务端权威,玩家只与游戏服通信)⇒ **中继容量按「服数」算,不按「玩家数」算**。
## 一、目标
把「覆盖网络上的 MMORPG(2D/2.5D) / MUD / 传奇类」设计成可落地方案:流量画像 · 与覆盖网络的映射 · 12 条关键设计细节 · 参考方案对照 · 反模式 · 游戏线落地顺序。
可判定「做完了没有」= 上述六项齐备,且**最匹配判定的依据(五条特征对照)已给出**。
## 二、只读前置
| # | 事实 | 核对方式(期望输出) |
|---|---|---|
| 1 | 玩家与游戏服是**长连接**(TCP/WebSocket/自定义 UDP)且**断线重连不踢人** | 本档 §3.1 第 2 条(设计要求) |
| 2 | 「房间」抽象**平台尚不存在**(现在是「每用户一个实例 + 会话」) | 档案 110 §五(群聊需新建,无房间抽象) |
| 3 | 存档 = **不可再生数据** ⇒ 直接套备份三层 | 档案 110 §二(不可再生 46.3 MB 口径) |
| 4 | 有公网 IP 的节点天然就是**游戏服 / 中继候选** | 档案 105 §1 |
| 5 | AOI 是控带宽的杀手锏:扇出从 O(N) 降到 O(k) | 本档 §1(九宫格,k≈20–80) |
## 三、范围
- **改什么**:⏳ 未开跑。方案面 = 服主接入(拨出 + 中继)· 房间层(组队/行会/频道)· 存档备份 · 跨区/跨线路由 · 会话恢复 + 连接迁移 · 副本临时实例。
- **不动什么**:⛔ 官方 dsh 主程序(R2)|⛔ 不把玩家连成 P2P 网状(**毫无必要**且徒增连接数)|⛔ 本轮不动服务器、不改代码。
- **明确排除**:❌ 3D 大世界强实时竞技(FPS / MOBA 64+)—— 需专用服务端 + 权威模拟,中继多一跳,P2P 无法反作弊。
## 四、决策点
**已定**
1. **游戏重点是 MMORPG(2D/2.5D) / MUD / 传奇类**(用户明确定调)⇒ 判定上修为「**最匹配**」,非 3D 强实时竞技。
2. **服务端权威不可让**(P2P 无法防作弊;且这类游戏天生服务端权威 ⇒ 反作弊问题自然解决)。
3. **对外降频 + 按变化发送**(⛔ 别把服务端内部帧率直接当对外频率)。
4. **社交功能直接复用「房间层」**(队伍/行会/世界频道/副本组 = 房间)⇒ 一次建房,聊天 + 组队 + 行会 + 频道全都有。
5. **反模式硬拦**:全图广播 · 信任客户端时间 · 对外频率=服务端帧率 · 每 tick 落盘 · 世界频道无限制推送 · 玩家 IP 一变就断线 · 单区无限扩容 · 把玩家连成 P2P 网状。
**未定**:会话恢复窗口(断线多久内可无缝续上,参数待定)。
## 五、步骤(§6 游戏线落地顺序;每步自带一次验证)
1. **服主接入**:无公网 IP 的机器能开服并被外网访问(拨出 + 中继)—— **最小可用形态** → 验证:外网玩家可连上 NAT 后的游戏服。
2. **房间层**(组队/行会/频道,与聊天共用)→ 验证:一次建房,四类社交容器同时可用。
3. **存档备份**(套用备份三层,**只备存档与配置**,不备可重建的客户端资源)→ 验证:恢复演练通过。
4. **跨区/跨线路由**(骨干节点承担)→ 验证:跨地图/跨线/合服有可用路径。
5. **会话恢复 + 连接迁移**(移动端体验)→ 验证:Wi-Fi↔蜂窝切换不掉线。
6. 副本临时实例、合服。
## 六、验收
| # | 口径 | 期望 |
|---|---|---|
| A | 每玩家带宽 | MUD **<5 KB/s** | 传奇 **10–50 KB/s** | 2D/2.5D MMO **20–80 KB/s** |
| B | 单节点承载 | MUD 数百人 | 传奇 100–300 人 | 2D/2.5D 300–500 人 |
| C | ⭐ 关键简化生效 | 中继容量**按服数算**(一个服 1~N 条中继,几百玩家不各占一条) |
| D | AOI 生效 | 扇出从 O(N=500) 降到 **O(k≈20–80)**(差 10 倍以上) |
| E | 反模式零命中 | §5 八条反模式逐条对照,无命中 |
| F | 未验证项透明 | §7 四条已列全 |
## 七、回滚
- **本档自身**:零改动 ⇒ 无回滚需要。
- **执行期**:§五 六步各自独立可回滚;⛔ **服务端权威不可回滚**(一旦允许客户端持有权威状态 = 可作弊,属红线)。
## 八、回报格式
执行会话回填:① 每步验证命令 + 实际输出 ② 本环境实测:中继承载 100–300 人游戏服的实际**带宽与抖动** ③ 443/TCP 兜底下长连接稳定性 ④ 会话恢复窗口实际取值 ⑤ 跨区转发延迟增量 ⑥ commit ⑦ 未完成项与卡点。
## 九、未验证项(勿当结论)
本环境实测:中继承载 100–300 人游戏服的实际带宽与抖动(**未实测**)|443/TCP 兜底通道下长连接的稳定性(UDP 封禁的企业网,**未实测**)|会话恢复窗口(**待定参数**)|跨区转发的延迟增量(**待实测**)。
---
## 附录 A · 原始规划正文(逐字保留 · 2026-09-16)
> 以下为工作区根 `覆盖网络_游戏专项_MMORPG与MUD_20260916.md` 的**原文全文**,仅删除其一级标题(避免与档案标题重复),
> 其余**一字未改**;本档的可判定部分以上方 8 段为准。
> 日期:2026-09-16 | 性质:**专项设计稿**(细化 `覆盖网络_补遗与参考方案_20260916.md` §一)
> 🟢 范围:只考虑技术实现;跨境数据合规由使用者自行考虑。
---
## 0. 判定修正(此前按 3D 强实时竞技评估,结论要改)
> 前文说"大规模 MMORPG 不合适" —— **那是针对 3D 大世界强实时**。用户明确重点是 **MMORPG(2D/2.5D)· MUD · 传奇类**,这三类**恰好是覆盖网络最匹配的应用**,甚至比群聊更契合。
| 特征 | FPS / MOBA(不适合) | **MMORPG / MUD / 传奇(适合)** |
|---|---|---|
| 权威归属 | 实时模拟需专用服,P2P 反作弊难 | **天生服务端权威** ⇒ 反作弊问题自然解决 |
| 延迟敏感 | <50 ms | **几百 ms 无感**(tick 驱动) |
| 广播方式 | 全员高频状态 | **AOI 视野广播(九宫格)** ⇒ 天然不放大 |
| 每玩家带宽 | 数十–数百 Kbps 且要求抖动小 | **数 KB/s ~ 数十 KB/s** |
| 扩展方式 | 单局 | **分区 / 分线** ⇒ 天然水平切分 |
**一句话**:这三类游戏的架构(服务端权威 + tick + AOI + 分区)**本身就是覆盖网络友好型的**,我们不需要为它改造什么,只需要提供"到达游戏服的可靠低延迟路径"。
---
## 1. 流量画像(决定容量与选路)
| 类型 | tick / 广播频率 | 每玩家带宽 | 单节点可承载 | 覆盖网络压力 |
|---|---|---|---|---|
| **MUD(文字)** | tick 0.25–1 s(文本行) | **< 5 KB/s** | 数百人 | **极轻**,中继也够 |
| **传奇类(2.5D 俯视)** | 服务端 20–50 Hz 内部;对外按变化/降频 | **10–50 KB/s** | 100–300 人 | 轻 |
| **2D/2.5D MMORPG** | 同上 + 技能/特效事件 | **20–80 KB/s** | 300–500 人 | 轻–中 |
**两处关键的省带宽机制(这类游戏的标准做法,直接沿用)**:
1. **AOI / 兴趣区域广播(九宫格)**:只广播**视野内**实体 ⇒ 扇出从 O(N=500) 降到 **O(k≈20–80)**,差 **10 倍以上**。这就是为什么 MMORPG 不会出现"广播风暴"。
2. **对外降频 + 按变化发送**:服务端内部 20–50 Hz 模拟,对客户端只发**变化**且可降到 5–10 Hz ⇒ 再省一半到八成。
---
## 2. 与覆盖网络的映射(**关键简化**)
```
玩家(任意网络) 游戏服(服主的机器)
┌──────────────┐ ┌──────────────────────┐
│ 玩家 A 家宽 │──直连──────▶│ │
│ 玩家 B 移动网 │──中继──────▶│ 服务端权威 + 分区/分线 │
│ 玩家 C 企业网 │──443/TCP──▶│ 存档 / AOI / tick │
└──────────────┘ └──────────────────────┘
```
> ⭐ **最重要的简化**:**玩家之间不需要互联**(服务端权威,玩家只与游戏服通信)。
> ⇒ 覆盖网络在这一场景里**只需解决一件事:让玩家可靠地到达游戏服**,而**不是**把玩家连成网。
> ⇒ 直接后果:**中继容量按"服数"算,不按"玩家数"算** —— 一个服只需要 1~N 条中继,几百个玩家不各占一条。
### 2.1 三类角色的接入需求
| 角色 | 需求 | 覆盖网络的作用 |
|---|---|---|
| **服主(无公网 IP)** | 让外网玩家能连进来 | **必须有**(拨出 + 中继/反向隧道)—— 这是核心价值 |
| **服主(有公网 IP)** | 直接开放端口 | 可选(只为跨地域优化) |
| **玩家** | 连上游戏服 | 直连为主;跨地域或对端在 NAT 后时走中继 |
⇒ 与"骨干层"完美衔接:**有公网 IP 的节点天然就是游戏服/中继候选**。
---
## 3. 关键设计细节(12 条)
### 3.1 网络与同步
1. **服务端时间权威**:一切 tick、冷却、移动校验以**服务端时钟**为准,**不信任客户端时间** ⇒ 这是防"加速外挂"的唯一正解(传奇私服最常见的作弊就是改本地时间/加速)。
2. **长连接 + 心跳**:这类游戏是**长连接**(TCP/WebSocket/自定义 UDP)。心跳要能区分"卡"与"断",且**断线重连不踢人**(回放窗口 + 状态快照)。
3. **连接迁移**:玩家 Wi-Fi ↔ 蜂窝切换会换 IP ⇒ 用**会话 token 恢复**而不是"IP 变了就当新连接"(否则玩家一走动就掉线)。
4. **对外降频 + 变化优先**:见 §1.2;**别把服务端内部帧率直接当对外频率**。
5. **AOI 用成熟算法**:九宫格(最常用)/ 十字链表 / 四叉树。⚠️ **不要用全图广播** —— 那是这类游戏唯一的"自找风暴"。
### 3.2 世界结构
6. **分区 / 分线(zone / shard)**:地图或线路 = 独立的模拟单元 ⇒ 天然的水平扩展点,也天然对应"一台机器跑一个区"。
7. **跨区 / 跨线转发**:玩家跨地图、跨线、跨服(合服)时需要转发 ⇒ **由骨干节点做跨区路由**(这部分流量是小头,但必须有一条路径)。
8. **副本 / 独立实例**:副本可以**临时开进程**(用完即销毁)—— 资源模型与"实例"一致。
### 3.3 数据与持久化
9. **存档策略**:热数据在内存 + **定期落盘/写日志**(不要每 tick 落盘);冷数据(离线玩家)批量归档。
10. **持久化与备份衔接**:这类游戏的存档是**不可再生数据** ⇒ 直接套用备份三层(本地快速恢复 + 对象存储主备份 + 网内第三副本),且**只备存档与配置,不备可重建的客户端资源**。
11. **节点故障的玩家恢复**:游戏服挂 ⇒ 玩家应能**落到另一个节点继续**(配合 tick 存档 + 会话恢复);这正是"迁移提速"那条在游戏场景的直接应用。
### 3.4 社交与复用
12. ⭐ **社交功能直接复用「房间层」**:**队伍 = 房间、行会 = 房间、世界/交易频道 = 房间、副本组 = 房间**。
⇒ 前面"群聊房间与游戏对局是同一个抽象"的结论在这里第二次兑现:**一次建房,聊天 + 组队 + 行会 + 频道全都有**。
⚠️ 但要注意**世界频道的扇出**:它是唯一"一人发、全网收"的点 ⇒ **必须限频 + 分片 + 拉取式**,否则就是唯一的风暴源。
---
## 4. 参考方案对照(这类游戏生态很成熟,别自研)
| 方向 | 参考方案 | 借什么 |
|---|---|---|
| **MUD 服务端** | **Evennia**(Python,现代)、FluffOS / LPMud、CircleMUD、Ranvier(JS) | tick 驱动世界模型、房间/对象/指令体系 |
| **传奇类(Mir2)服务端** | 开源 **Mir2 服务端模拟器**(多份社区实现)、HeroM2 类引擎 | 格子地图、服务端权威移动校验、封包协议 |
| **2D/2.5D MMO 服务端框架** | **Skynet**(Lua,分区分服经典)、**Pomelo**(Node.js 分布式)、**KBEngine**、**ET**(C# 双端)、Colyseus、**Orleans**(虚拟 Actor) | 分区分线、跨服路由、actor/实体模型 |
| **通用游戏后端** | **Nakama**(房间 + 匹配 + 持久化 + 排行,开源) | 直接可用的社交/账号/存储能力 |
| **AOI 算法** | 九宫格 / 十字链表 / 四叉树 / R-tree | 视野广播的成熟实现 |
| **联机传输** | KCP / enet / QUIC;WebRTC DataChannel(不可靠模式) | 类 UDP 的低延迟可靠传输 |
| **客户端** | Cocos / LayaAir / Phaser / Godot(2D) | 与 Web 客户端壳集成的天然选择 |
**国内生态提示**:传奇/2D MMO 的"一台机器一个区 + 分线"是**行业标准做法**,与我们"用户自己开服 + 骨干中继让外网可达"的模型天然契合 —— 不需要发明新范式。
---
## 5. 反模式(这类游戏特别容易踩的)
| # | 反模式 | 后果 |
|---|---|---|
| 1 | **全图广播**(不做 AOI 裁剪) | 唯一的自找广播风暴 |
| 2 | **信任客户端时间** | 加速外挂横行 |
| 3 | **对外频率 = 服务端帧率** | 带宽浪费数倍 |
| 4 | **每 tick 落盘** | IO 打满 |
| 5 | **世界频道无限制推送** | 一人发言全员收 = 放大点 |
| 6 | **玩家 IP 一变就断线** | 移动玩家体验崩塌 |
| 7 | **单区无限扩容** | 该分区就分区,别硬撑单进程 |
| 8 | **把玩家连成 P2P 网状** | 毫无必要(服务端权威)且徒增连接数 |
---
## 6. 落地顺序(游戏线)
1. **服主接入**:无公网 IP 的机器能开服并被外网访问(拨出 + 中继)—— **这是最小可用形态**。
2. **房间层**(组队/行会/频道,与聊天共用)。
3. **存档备份**(套用备份三层,只备存档与配置)。
4. **跨区/跨线路由**(骨干节点承担)。
5. **会话恢复 + 连接迁移**(移动端体验)。
6. 副本临时实例、合服。
---
## 7. 未验证项
| # | 项 | 状态 |
|---|---|---|
| 1 | 本环境实测:中继承载 100–300 人游戏服的实际带宽与抖动 | ⚠️ 未实测 |
| 2 | 443/TCP 兜底通道下长连接的稳定性(UDP 封禁的企业网) | ⚠️ 未实测 |
| 3 | 会话恢复窗口(断线多久内可无缝续上) | 📋 待定参数 |
| 4 | 跨区转发的延迟增量 | 📋 待实测 |
@@ -0,0 +1,202 @@
# 109 · 覆盖网络 · 调研-游戏网络特征与群聊上限
- 日期:2026-09-16 | 状态:📋 **规划态**(**全网调研稿**;数值均标注来源口径,未在本环境实测的一律标出)
- 来源:工作区根 `覆盖网络_调研_游戏网络特征与群聊上限_20260916.md`(正文见 附录 A)
- 层级:专项调研(**数值底座**)| 配套档案 **108**(游戏专项)· 104(全球架构复盘)
- 🟢 范围:只考虑技术实现;跨境数据合规由使用者自行考虑。
> **TL;DR**
> 两部分:① **这类游戏的网络特征**(传奇 / MMORPG / MUD 的每玩家带宽、同步间隔、承载、延迟/丢包门槛);
> ② **单房间群聊的人数上限** —— 🔑 关键结论:**上限不是「人数」而是「扇出预算」**,且 **presence(N²)比消息更早爆**(1000 人房 ≈16,700 次/秒)。
> 给我们场景特有的上限:**单房间实际上限由「presence + agent 预算」决定**,不是由消息扇出决定。
## 一、目标
为容量规划提供**可引用的数值底座**:游戏侧(每玩家 2–20 KB/s、jitter<20 ms 等)与群聊侧(产品上限对照、三种分发模型的爆炸点、分档建议)。
可判定「做完了没有」= 两部分数值齐备 + **每条标注是行业资料口径还是本环境实测** + 结论可换算到本方案。
## 二、只读前置
| # | 事实 | 核对方式(期望输出) |
|---|---|---|
| 1 | 本档全部游戏数值均为**行业资料口径**,非本环境实测 | 逐条对照 §1.1/§1.2/§1.3 的来源标注 |
| 2 | 本环境唯一相关实测 = 跨云 **~22 KB/s**(只能作下界) | 47↔106 实测(档案 110 §三) |
| 3 | 我们场景的 presence 量级可与 §2.2 公式对齐 | `1000 × 1000 / 60` ≈ **16,700 次/秒** |
| 4 | 平台现**无「房间」抽象** ⇒ 群聊属新增能力,不是开关 | 档案 110 §五 |
| 5 | 抖动门槛 **>20 ms 即 desync** 是选路的判据来源 | 本档 §1.2 与 §1.4 第 2 条 |
## 三、范围
- **改什么**:⏳ 无实施动作 —— 本档是**调研**,产出为数值与判据,供 104/107/108/112 引用。
- **不动什么**:⛔ 本轮不动服务器、不改代码、不改文档库其它文件。
- 🟢 边界:⛔ **不得把本档的行业口径数字当作本环境实测结论**(每条均已标注)。
## 四、决策点
**已定(本档给出的判据,已被后续档案采纳)**
1. **容量按「服」算,不按「玩家」算**(服务端权威 ⇒ 玩家之间不互联)⇒ 中继需求 = 服数 × 1~N。
2. **游戏侧要盯的是「抖动」不是「带宽」**(jitter > 20 ms 即 desync)⇒ 中继链路质量差(如跨云 22 KB/s)**延迟低也没用**。
3. **上行是主方向**(服务器 → 玩家)⇒ 规划时看服务器上行。
4. **单房间上限定义为「扇出预算」而不是人数** ⇒ 先定"单节点每秒可承受投递数",再反推人数上限(可随架构演进变大,而不是魔法数字)。
5. **混合模型**(小群扇出 / 大群拉取)—— Telegram 实际做法,服务端只维护**消息时序 + 版本游标**。
6. **presence 收敛 = 只订阅「当前可见成员列表」**(Slack 做法)⇒ 流量降 5 倍。
7. **压测必须用攻城场景**(数百人同屏、带宽翻倍、同步间隔收紧到 50–100 ms),不能用平峰。
**未定**:本环境能否满足 jitter<20 ms(**未实测,且这是游戏可玩性的决定项**)。
## 五、步骤
**本档无实施步骤**(调研稿)。其**结论已被下列档案转化为可执行步骤**:
- 游戏侧 → **档案 108 §五**(服主接入 → 房间层 → 存档备份 → 跨区路由 → 会话恢复 → 副本/合服)
- presence 与群聊上限 → **档案 112 §1**(presence 七条落地做法 + 大房特殊策略)
- 数值校准 → **档案 107 §六**(未验证项转为实测项)
## 六、验收
| # | 口径 | 期望 |
|---|---|---|
| A | 游戏数值可引用 | 传奇每人 0.5–20 KB/s;MMORPG 80–800 Kbps;MUD <1 KB/s —— 均标来源 |
| B | 群聊上限对照 | Telegram 200,000 | WhatsApp 2,048 | Discord 单频道 100K+ 在线 |
| C | 分档建议 | ≤100 / 100–2,000 / 2,000–50,000 / >50,000 四档,各有架构要求与判据 |
| D | 本方案特有上限 | 明确「presence + agent 预算」比消息扇出更早触顶 |
| E | 未验证项透明 | 第三部分五条已列全 |
## 七、回滚
- **本档自身**:零改动 ⇒ 无回滚需要。
- ⛔ **不得作为实测依据被引用**:本档数值是**行业资料口径**,任何"已经达标"的结论都必须另有本环境实测支撑。
## 八、回报格式
执行会话(或后续校准会话)回填:① 自建服实测的每玩家带宽与同步间隔(与 §1.1 对照)② 中继链路 jitter 分布 ③ 攻城战压测结果 ④ presence 收敛实际降幅(5× 是否可达)⑤ agent 放大系数实测 ⑥ 取数时间与命令。
## 九、未验证项(勿当结论)
上述游戏数值均为**行业资料口径**,非本环境实测(**需按自建服实测校准**)|中继链路能否满足 **jitter < 20 ms**(比带宽更关键,**未实测,且这是游戏可玩性的决定项**)|攻城战(数百人同屏)在本方案的压测结果(**未做**)|presence 在本方案下的实际收敛效果(5× 是否可达,**未实测**)|agent 参与的放大系数实测(**未实测**)。
---
## 附录 A · 原始规划正文(逐字保留 · 2026-09-16)
> 以下为工作区根 `覆盖网络_调研_游戏网络特征与群聊上限_20260916.md` 的**原文全文**,仅删除其一级标题(避免与档案标题重复),
> 其余**一字未改**;本档的可判定部分以上方 8 段为准。
> 日期:2026-09-16 | 性质:**全网调研稿**(数值均标注来源口径;未在本环境实测的一律标出)
> 配套:`覆盖网络_游戏专项_MMORPG与MUD_20260916.md`|`覆盖网络_全球架构复盘_20260916.md`
> 🟢 范围:只考虑技术实现;跨境数据合规由使用者自行考虑。
---
## 第一部分 · 这类游戏的网络特征
### 1.1 传奇类(中文运维资料口径,最具体)
| 参数 | 数值 |
|---|---|
| **每人带宽** | **文字聊天 0.5 KB/s | 普通战斗 2–5 KB/s | 攻城战 10–20 KB/s**;另一口径:单用户平均上行 **10–20 KB/s** |
| **带宽估算公式** | `所需带宽 = 玩家数 × 100 Kbps ÷ 8`;100 人 ≥ 2 Mbps | 500 人 ≥ 10 Mbps | 1000 人 ≥ 50 Mbps |
| **实战推荐带宽** | 50 人 5 Mbps | 200 人 10 Mbps | 500 人 20 Mbps+(均含冗余) |
| **同步间隔** | 常规 **100–200 ms(5–10 Hz)**;**攻城/大型团战 50–100 ms(10–20 Hz)** |
| **引擎帧数设置** | <100 人 20 帧 | ≤200 人 25–30 帧 | ≈300 人 35–40 帧 |
| **发送间隔 / 缓存** | 网络发送间隔 20–30 ms;发送缓存 4096 B;接收缓存 8192 B;最大接收 1024–2048 KB/s |
| **承载** | 单区常规 **1000–5000 人**(TCP 并发 2000–10000;TPS 500–2000) |
| **延迟 / 丢包** | 延迟 ≤ **50 ms**,丢包 < 1% |
| **内存经验值** | 每 50 名玩家 ≈ 1 GB(+20% 缓冲);1000 人区服建议 16 GB |
| **峰值场景** | **攻城战:数百玩家同屏**,带宽翻倍至 **80–100 Mbps**(1000 人口径),CPU/内存压力最大 |
### 1.2 MMORPG(英文资料口径,含 3D 参照)
| 参数 | 数值 |
|---|---|
| **每玩家带宽** | 同步 **10–20 Hz**;兴趣域实体 **50–100 个**;每实体 **20–50 B**;每包 **1–5 KB** ⇒ **单客户端 80–800 Kbps**(该上限是 3D 现代 MMO 口径;**2D/传奇类取低段**) |
| **500 人峰值** | **200–500 Mbps**;端口最低 **1 Gbps**,500+ 用 10 Gbps |
| **延迟门槛** | **< 100 ms**;⚠️ **抖动(jitter)> 20 ms 就会造成位置与战斗 desync** |
| 数据库 | MNORPG 是**持续写入**(每次拾取/战斗/交易都写)⇒ **DB I/O 是隐藏瓶颈**,>500 人建议数据库独立机器 |
| 优化 | **兴趣域(AOI)是控制带宽的"杀手锏"**;delta 压缩可再减 **50%+** |
### 1.3 MUD(文字)
- 纯文本行 ⇒ 每玩家 **< 1 KB/s**(与棋牌/回合制同档);瓶颈是**并发连接数**(内存与文件句柄),不是带宽。
- tick 0.25–1 s;**延迟容忍度最高**,跨洲也可玩。
### 1.4 对覆盖网络的五条推论(这一节才是我们要的)
1. **带宽量级很小**:这类游戏单玩家 **2–20 KB/s**,1000 人也就 **20–100 Mbps** —— **中继扛得住**,不像视频/大文件。
2. ⚠️ **真正要盯的是"抖动",不是"带宽"** —— 业界口径 **jitter > 20 ms 就会 desync**。⇒ 中继路径的价值不是省带宽,而是**抖动是否可控**;中继链路质量差(如实测那条 22 KB/s 的跨云)**延迟低也没用**。
3. **上行是主方向**(服务器 → 玩家),下行只是操作指令 ⇒ 规划时**看服务器上行**。
4. **容量按"服"算,不按"玩家"算**(服务端权威 ⇒ 玩家之间不互联)⇒ 中继需求 = 服数 × 1~N,而不是玩家数。
5. **攻城战就是压测基准**:数百人同屏、带宽翻倍、同步间隔收紧到 50–100 ms ⇒ **压测必须用攻城场景**,不能用平峰。
---
## 第二部分 · 单房间群聊的人数上限
### 2.1 产品上限对照(真实产品,可作为能力标尺)
| 产品 | 单房间上限 | 备注 |
|---|---|---|
| **Telegram 群组** | **200,000** 成员(频道无限) | 十万级群**切换为拉取模型**;慢速模式间隔 10 s–1 h |
| **WhatsApp 群** | **2,048** 成员 | fanout = 2047,典型"纯扇出"上限 |
| **Discord** | 单频道 **100K+ 在线**;单 guild **25M 成员**(2025-09) | 1M 并发/guild(72 台 ScyllaDB 存万亿消息) |
| 国内 IM | 数百 → 两千量级 | 口径随产品变化,此处不列精确值 |
### 2.2 为什么上限不是"人数"而是"扇出预算"
**三种模型与各自的爆炸点**:
| 模型 | 写放大 | 读放大 | 结论 |
|---|---|---|---|
| **纯扇出**(服务端逐人推送) | **极高**:20 万人群一条消息 = 20 万次写入 | 低 | **小群王道,大群自杀** |
| **纯拉取**(只存一份,各端按游标读) | 极轻 | **高**:20 万人同时上线打穿热点 | 实时性差,需长连接通知配合 |
| **混合(Telegram 实际做法)** | 小群扇出 / 大群拉取 | 中 | **推荐**:服务端只维护**消息时序 + 版本游标**,客户端按游标增量拉 |
**两个必须算的放大点(附实际数字)**:
1. **消息扇出**:20 万人 × 500 条/分钟 = **1 亿次推送/分钟** ⇒ 纯扇出不可能。
Discord 口径:单频道 **30K 在线 × 10 msg/s = 30 万次"权限校验后的投递"/秒** —— 注意**权限检查(RBAC)是 CPU 热路径**。
2. **在线状态(presence)是 N² 问题**:每人订阅所有可见成员的状态,每次变化扇出给所有订阅者。
⚠️ **算一下就发现它比消息更早爆**:1000 人房、每人每分钟变化一次 ⇒ `1000 × 1000 / 60` = **≈16,700 次/秒** —— **千人房就已经是热点**。
✅ 业界解法(Slack):**只订阅"当前可见成员列表"** ⇒ presence 流量降 **5 倍**。
### 2.3 关键工程机制(可直接照抄)
| 机制 | 作用 |
|---|---|
| **pub/sub 聚合** | 一条消息**每个 relay/gateway 节点只推一次**,而不是每个接收者一次 —— 这是把 30,000 次推送降下来的关键 |
| **版本游标 + 增量拉取** | 客户端只拉游标之后的增量;翻历史才回溯 |
| **presence 收敛** | 订阅范围裁剪(只可见者)+ 批量合并 + 降频 + 最终一致 |
| **RBAC 缓存 + 版本化失效** | 权限检查在热路径 ⇒ 必须缓存,且要能失效 |
| **慢速模式(slow mode)** | 把限流产品化(大群必备) |
| **客户端侧** | 本地 SQLite 缓存、成员**懒加载**、消息合并/分片渲染(防界面卡死)、多设备靠 sequence 对齐 |
| **三平面分离** | 连接平面(gateway)/ 协调平面(房间进程)/ 存储平面(写重型库 + 搜索)各自独立扩展 |
| **一致性取舍** | **最终一致(1–2 s 窗口可接受)+ 房间内严格有序** |
### 2.4 给我们的**分档建议**(回答"单房间上限")
| 房间规模 | 架构要求 | 判据 |
|---|---|---|
| **≤ 100 人** | 纯扇出即可 | 无压力 |
| **100 – 2,000 人** | **纯扇出可行**,但必须:presence 合并 + 消息限频 + 权限缓存 | 千人房的 presence 已是热点(≈1.6 万次/秒) |
| **2,000 – 50,000 人** | **必须混合**:pub/sub 聚合 + 游标拉取 + presence 只推可见者 + 慢速模式 | 扇出成本随人数线性,聚合后按节点数而非人数 |
| **> 50,000 人** | **只能拉取模式**,公告/只读为主,presence 大幅弱化 | Telegram 20 万即此档 |
> **建议把上限定义为"扇出预算"而不是人数**:先定"单节点每秒可承受的投递数",再由它反推房间人数上限 —— 这样上限可以随架构演进(加 gateway)而变大,而不是一个魔法数字。
### 2.5 我们场景特有的上限(**比技术扇出更早触顶**)
- **agent 入群后,真正的放大点不是消息,而是"agent 之间的互相激发"**:
一个房间若有 K 个 agent,且不加约束 ⇒ 消息量可指数增长。
- ⇒ 必须按 **`agent 数 × 触发频率`** 单独设预算(每 agent 每 N 分钟最多 M 条 + 静默期 + **禁止 agent 直接触发 agent**)。
- ⇒ 结论:**对我们而言,单房间的实际上限由"presence + agent 预算"决定,而不是由消息扇出决定** —— 后者在千人量级还远远不是瓶颈。
---
## 第三部分 · 未验证项(勿当结论)
| # | 项 | 状态 |
|---|---|---|
| 1 | 上述游戏数值均为**行业资料口径**,非本环境实测 | ⚠️ 需按自建服实测校准 |
| 2 | 中继链路能否满足 **jitter < 20 ms**(比带宽更关键) | ⚠️ **未实测,且这是游戏可玩性的决定项** |
| 3 | 攻城战(数百人同屏)在本方案的压测结果 | ⚠️ 未做 |
| 4 | presence 在本方案下的实际收敛效果(5× 是否可达) | ⚠️ 未实测 |
| 5 | agent 参与的放大系数实测 | ⚠️ 未实测 |
@@ -0,0 +1,220 @@
# 110 · 覆盖网络 · 答疑-群聊备份迁移保密
- 日期:2026-09-16 | 状态:📋 **规划态**(技术答疑稿;未实施)
- 来源:工作区根 `覆盖网络_答疑_群聊备份迁移保密_20260916.md`(正文见 附录 A)
- 层级:专项答疑(四问)| 承接档案 104;被 108(房间层)· 111 · 112(备份/保密)引用
- 🟢 范围:只考虑技术实现;跨境数据合规由使用者自行考虑。
> **TL;DR**
> 四问四答:① **群聊 + agent 入群** = ✅ 可实现(群聊是**应用层**的事,覆盖网络只解决「可达」);② **备份** = **主备份优先对象存储**,
> 覆盖网络只当**搬运通道与第三副本**(P2P 副本无 SLA、可误删,**不适合当存档**);③ **迁移提速** = 按收益 7 条,
> **最大那一招是「不搬可重建的」**(46.3 MB vs 2.9 GiB ⇒ 约 64×);④ **保密** = 三层加密 + 元数据保护,**当前最大缺口是身份(共享令牌 → 一机一钥)**。
## 一、目标
回答四个具体问题(群聊与 agent 参与 / 服务器用户数据备份方案 / 迁移服务器速度优化 / 传输保密性),每问给出**可执行做法与判据**。
可判定「做完了没有」= 四问各有明确结论 + 可落地手段 + 与现有平台的「现成度」判定。
## 二、只读前置
| # | 事实 | 核对方式(期望输出) |
|---|---|---|
| 1 | 平台**没有「房间」抽象**(现在是「每用户一个实例 + 会话」)⇒ 群聊 = 新增能力 | 读平台现状 / 档案 108 §2.1 |
| 2 | 备份基础已有:`backup.sh` + cron + `/opt/dsh/backups/` + 恢复演练 | 读 `scripts/` 与 `02-运维手册.md` |
| 3 | 不可再生 **46.3 MB** / 可重建 **2.9 GiB** | 备份口径实测记录 |
| 4 | 47→106 直连实测 **~22 KB/s**(46.3 MB 需 ~35 分钟) | 跨云实测记录 |
| 5 | 节点身份现为**共享 bearer**(无法吊销单台)⇒ 保密层最大缺口 | `src/worker/agent.ts` 头部自陈 |
## 三、范围
- **改什么**:⏳ 未开跑。方案面 = 群聊房间层 + agent 成员类型 · 备份补「对象存储主层 + 只备不可再生」· 迁移补「多流并行 + 惰性迁移」· 身份换一机一钥 + E2EE。
- **不动什么**:⛔ 官方 dsh 主程序(R2)|⛔ 本轮不动服务器、不改代码。
- **明确不做**:⛔ 不用那条慢链路(22 KB/s)当备份/迁移通道 —— 备份上传应走**各自到公网/对象存储**的路径。
## 四、决策点
**已定**
1. **群聊 = 应用层的事**,覆盖网络只提供「可达」,**不提供**「有序、去重、不丢」⇒ 群聊必须自带:消息 ID(内容寻址/哈希)· 因果/逻辑时钟 · 送达确认 + **离线补拉(拉取式)**· 房间级权限。
2. **✅ 用户选:备份主层用对象存储**(自建 MinIO 或云 OSS/COS),**覆盖网络只当搬运通道与第三副本**。
3. **只备不可再生数据**(+ 附一份重建清单)⇒ 体积降一个数量级。
4. **上传前先加密**(服务端/对象存储不持有明文);**校验和 + 版本化 + 防误删**;**恢复演练自动化**。
5. **传输保密 = 三层加密 + 元数据保护**,**一句话判据:中继只能看到密文与元数据,控制面只能看到密文与身份** —— 任何一条不满足即视为不合格。
6. **agent 四条硬约束**:⛔ 禁止 agent 直接触发 agent(只有**人的消息**能触发)· 每轮发言预算 · 静默期 · 房间级全局速率上限 + 排队。
**未定**:群聊/agent 的具体成员类型与发言预算参数(M / N / 房间上限,需压测标定)。
## 五、步骤(每条自带一次验证)
**A · 群聊与 agent**
1. 选分发拓扑(**推荐混合**:小群网状 / 大群区域汇聚 / 离线补拉)→ 验证:大群**禁止「每人每条广播给全体」**。
2. 群聊自带四项(消息 ID / 逻辑时钟 / 送达确认 + 补拉 / 房间权限)→ 验证:去重与乱序场景可正确收敛。
3. agent 作为**独立对等成员**(有自己的密钥与地址,身份绑定主人、权限可单独授)→ 验证:agent 四条硬约束在压测下生效。
**B · 备份**
4. 三层组合(本地快速恢复 / **对象存储主备份** / 网内第三副本)→ 验证:RTO 与不可变性达标。
5. 只备不可再生 + 增量去重 + 上传前加密 → 验证:备份集体积降一个数量级。
6. 恢复演练自动化 → 验证:演练通过。
7. 备份走各自到对象存储的路径(**不走慢链路**)→ 验证:备份期间交互流量 p95 延迟不变。
**C · 迁移提速**(按收益排序)
8. 不搬可重建的(~64×,已在做)→ 9. 分片并行 + 多流 → 10. 先压缩再传 → 11. 增量/块级 diff → 12. 多路径并行 → 13. 惰性迁移 → 14. 经公网对象存储中转。**断点续传是前提**。
**D · 保密**
15. 三层加密(隧道层 / 应用层 E2EE / 静态层)→ 16. 一机一钥 + 密钥轮换吊销 + 群密钥轮换 + **校验控制面签名** → 17. 元数据保护(最小网络地图 / 不透明 ID / 隐私模式强制走中继)。
## 六、验收
| # | 口径 | 期望 |
|---|---|---|
| A | 群聊拓扑 | 已选一种(推荐混合)且说明取舍 |
| B | 备份主层 | **对象存储**为主;覆盖网络=通道+第三副本(非主备份) |
| C | 迁移 | 以**实测吞吐**为准,目标把 22 KB/s 提到链路可支持的量级 |
| D | 保密判据 | 「中继只见密文与元数据 / 控制面只见密文与身份」两条均满足 |
| E | 现成度透明 | §五 五条已判定(群聊❌需新建 / agent⚠️部分 / 备份✅基础已有 / 迁移⚠️部分 / 保密⚠️缺口在身份) |
## 七、回滚
- **本档自身**:零改动 ⇒ 无回滚需要。
- **执行期**:四块(群聊 / 备份 / 迁移 / 保密)互相独立,各自可回滚;⚠️ **备份改造**须保留旧路径直到恢复演练验证通过。
## 八、回报格式
执行会话回填:① 每步验证命令 + 实际输出 ② 群聊拓扑选型与理由 ③ 备份三层落点与恢复演练结果 ④ 迁移实测吞吐(与 22 KB/s 基线对比的倍数) ⑤ 加密三层各自的落地位置与判据验证 ⑥ commit ⑦ 未完成项与卡点。
## 九、未验证项 / 待办
群聊房间层的具体成员模型与发言预算参数(**待压测标定**)|E2EE 的实现路径(**需新增**)|多路径并行与惰性迁移的实际收益(**待评估**)|一机一钥迁移期间的兼容期处理(**待设计**)。
---
## 附录 A · 原始规划正文(逐字保留 · 2026-09-16)
> 以下为工作区根 `覆盖网络_答疑_群聊备份迁移保密_20260916.md` 的**原文全文**,仅删除其一级标题(避免与档案标题重复),
> 其余**一字未改**;本档的可判定部分以上方 8 段为准。
> 日期:2026-09-16 | 性质:**技术答疑**(承接 `覆盖网络_全球架构复盘_20260916.md`)
> 🟢 **范围**:只考虑技术实现;跨境数据合规由使用者自行考虑。
---
## 一、群聊 + 「用户配置的 agent 也在群里互动」——✅ 可以实现
**关键判断**:群聊**不是覆盖网络的机制**,它是**应用层**的事。覆盖网络只解决"参与者散在各种网络里也能互相到达"——而这恰好是群聊最麻烦的那一半。所以两者是**互补**,不是一回事。
### 1.1 三种分发拓扑(必须选一种,推荐第三种)
| 拓扑 | 优点 | 缺点 |
|---|---|---|
| 中心房间(消息过服务端) | 简单、天然全序、易持久化 | 中心带宽与单点;隐私面大 |
| 网状(成员间直连分发) | 省中心 | N²、顺序与送达确认难做 |
| **混合(推荐)** | 小群网状 / 大群走区域汇聚节点;离线补拉 | 实现复杂度最高,但可控 |
### 1.2 覆盖网络给不了的,必须在应用层补
覆盖网络只提供"**可达**",**不提供**"有序、去重、不丢"。所以群聊必须自己带:
1. **消息 ID**(内容寻址/哈希)⇒ 去重
2. **因果/逻辑时钟** ⇒ 排序(无需全局时钟)
3. **送达确认 + 离线补拉**(**拉取式**,不是推送式)
4. **房间级权限**:加入房间才可见 —— 与"接入 ≠ 可见"一致
### 1.3 Agent 作为群成员的四个要点
- **身份**:agent 是一个**独立的对等成员**(有自己的密钥与地址),但**身份绑定其主人**、**权限可单独授**(可只读、可仅在被 @ 时发言)。
- **运行位置决定数据面**:跑在用户自己机器上 ⇒ 消息不出去;跑在服务器 ⇒ 平台要路由给它。
- ⚠️ **最大的坑 = agent 互相激发造成无限循环**(A 说 → B 回 → A 再说)。**必须内建四条硬约束**:
1. **禁止 agent 直接触发 agent** —— 只有**人的消息**能触发 agent 发言(切断自激环);
2. **每轮发言预算**(每个 agent 每 N 分钟最多 M 条);
3. **静默期**(发言后冷却);
4. **房间级全局速率上限** + 排队(多 agent 同时发言时按序,不刷屏)。
- **风暴防护**:群聊是典型"推送放大点"(1 条消息 × N 成员)⇒ 大群**禁止"每人每条广播给全体"**,改"摘要比对 + 按需拉取"。
---
## 二、服务器用户数据备份 —— **主备份优先对象存储,覆盖网络只当搬运通道与第三副本**
> 用户问「优先还是云存储方案」。**答案是分层组合,不是二选一**;但从"备份的本质指标"看,**主备份应当优先对象存储**。
### 2.1 三层组合(推荐)
| 层 | 落点 | 作用 | 为什么 |
|---|---|---|---|
| **快速恢复层** | **本地盘** | 最近 N 份,恢复最快 | RTO 最短、零流量 |
| **主备份层** | **对象存储**(自建 MinIO 或云 OSS/COS) | 长期、异地、**不可变** | 备份的核心是**可恢复性 + 不可变**,对象存储天然给 SLA、版本化、生命周期 |
| **第三副本 / 通道** | **覆盖网络内的自有节点** | 异地冗余 + 搬运 | 零月费、跨地域;但**没有 SLA** |
### 2.2 为什么"覆盖网络不适合当主备份"
P2P/网内副本的根本弱点:**对端是否在线不由你控制**,没有 SLA、没有不可变、容易被误删或版本混乱。**它适合"搬运",不适合"存档"。**
### 2.3 工程要点(决定成本与可用性)
1. **只备不可再生数据**:已有实测口径 —— 不可再生 **46.3 MB**、可重建 **2.9 GiB** ⇒ **只备前者 + 附一份重建清单**,体积降一个数量级。
2. **增量 + 内容寻址去重**(同一份只存一次)。
3. **上传前先加密**(服务端/对象存储不持有明文)。
4. **校验和 + 版本化 + 防误删**(对象存储的 lifecycle / 不可变桶)。
5. **恢复演练自动化**(现有平台已有恢复演练先例,保持)。
6. ⚠️ **别用那条慢链路当备份通道**:跨云实测 **22 KB/s** —— 备份上传应走**各自到公网/对象存储**的路径,而不是两地直连。
---
## 三、迁移服务器速度优化
**现状痛点**:47→106 直连实测 **~22 KB/s**(46.3 MB 需 ~35 分钟)。
**按收益排序的手段**:
| 序 | 手段 | 收益 |
|---|---|---|
| 1 | **不搬可重建的**(只搬 46.3 MB,而非 2.9 GiB) | **~64×** —— 已在做,最大的那一招 |
| 2 | **分片并行 + 多流** | 单流受 BDP(带宽时延积)限制;多流才能吃满链路 —— 实测脚本已在用分片 |
| 3 | **先压缩再传** | 文本/JSON 常见 10:1 |
| 4 | **增量 / 块级 diff**(rsync 式或内容寻址) | 只传变化块 |
| 5 | **多路径并行**(直连 + 中继同时传) | 覆盖网络带来的新能力;⚠️ 需给中继留额度,别打满 |
| 6 | **惰性迁移**(内容寻址 + 按需拉取) | 把"前置全量"变成"用哪个拉哪个" —— 体验上最优 |
| 7 | **经公网对象存储中转** | 两地直连慢时,各自到云的带宽往往更快 |
**断点续传是前提**(不追求一次传完;分块落盘、可续)。**验收**:以实测吞吐为准,目标把 22 KB/s 提到链路可支持的量级。
---
## 四、如何确保用户信息在覆盖网络传输中的保密性
### 4.1 三层加密(缺一层都不算保密)
| 层 | 机制 | 防谁 |
|---|---|---|
| **隧道层** | WireGuard / Noise 端到端加密;**中继只转发密文、不解密** | 中间网络、中继运营者 |
| **应用层(E2EE)** | 消息在应用层再加一层;密钥只在成员间分发 | **连自己的控制面/中继也读不到内容** |
| **静态层** | 磁盘与备份加密(上云前先加密) | 存储侧泄露 |
### 4.2 身份与密钥(当前最大的缺口)
1. **一机一钥**替换共享令牌(现状是共享 bearer,无法吊销单台)。
2. **密钥轮换与吊销**(会话密钥定期 rekey —— WireGuard 已有基础)。
3. **群聊的群密钥轮换**:成员变更即轮换 ⇒ **前向保密**。
4. **必须校验控制面签名**:否则可以下发假的网络地图(假身份)⇒ 中间人。
### 4.3 元数据保护(最容易忽略的一层)
隧道只保护**内容**,控制面与中继仍能看到**谁连谁、何时、流量多大**。要减少暴露:
- **最小网络地图**:只下发"你确实需要连接的"对端,不下发全网名单。
- **不透明 ID**:中继侧不用真实用户名/主机名。
- **隐私模式**:直连会**向对方暴露自己的真实 IP**(P2P 的固有代价)⇒ 需要隐私的流量**强制走中继**,不暴露 IP。
### 4.4 一句话判据
> **"中继只能看到密文与元数据,控制面只能看到密文与身份"** —— 任何一条不满足即视为不合格。
---
## 五、与现有平台的关系(这三件哪些是现成的)
| 需求 | 现成度 | 说明 |
|---|---|---|
| 群聊 | ❌ **需要新建** | 平台现在是"每用户一个实例 + 会话",**没有"房间"抽象** ⇒ 这是新增能力,不是开关 |
| Agent 入群 | ⚠️ 部分 | agent 能力有,但"作为群成员"需新增成员类型 + 发言预算机制 |
| 备份 | ✅ **基础已有** | `backup.sh` + cron + `/opt/dsh/backups/` + 恢复演练;需补"对象存储 + 只备不可再生" |
| 迁移提速 | ⚠️ 部分 | 分片已在用;缺多流并行、惰性迁移 |
| 传输保密 | ⚠️ **缺口在身份** | 隧道加密已有;**共享令牌 ⇒ 一机一钥**是硬前置;E2EE 需新增 |
@@ -0,0 +1,250 @@
# 111 · 覆盖网络 · 补遗与参考方案
- 日期:2026-09-16 | 状态:📋 **规划态**(补遗复盘稿;未实施)
- 来源:工作区根 `覆盖网络_补遗与参考方案_20260916.md`(正文见 附录 A)
- 层级:专项补遗| 承接档案 104 · 110;被 108(游戏判定修正)引用
- 🟢 范围:只考虑技术实现;跨境数据合规由使用者自行考虑。
> **TL;DR**
> 四部分:① **互联游戏可行性**(✅ 支持,但**由游戏形态决定**;优先做「**只传输入**」的锁步/回合制);
> ② **补遗 24 条**(身份与账户 / 寻址与名字 / 接入与可见性 / 自检与选路 / 流量与公平 / 移动端弱网 / 升级版本自愈 / 可观测);
> ③ **参考方案对照**(10 个能力域的现成物,**别自研**);④ **反模式 12 条**(踩了就出事,逐条对照)。
> ⭐ 最划算的一处架构复用:**群聊房间与游戏对局是同一个模型** ⇒ 一次建房间层,群聊 + 游戏 + 协作 + 看板共用。
## 一、目标
补齐前面各档案未覆盖的项(24 条)+ 给出可借鉴的现成物清单 + 反模式清单,并回答「互联游戏是否可行」。
可判定「做完了没有」= 四部分齐备,且**补遗 24 条每条都能落到一个能力域**。
## 二、只读前置
| # | 事实 | 核对方式(期望输出) |
|---|---|---|
| 1 | 各档案已有明确分工(见 §三 表格「已有明确分工」) | 档案 104 §1–§5(五层 / 12 特性 / 流量)· §四(风暴)· §五(流量组织) |
| 2 | ⚠️ 各档案**已有明确分工**,本档只补缺 | 逐条比对 104 / 105 / 106 / 107 / 108 / 109 / 110 |
| 3 | 平台已有域名 `alotbuy.com` ⇒ 可做子域解析(MagicDNS 式) | 读 `01-规划与架构.md` 域名接入 |
| 4 | 各档案**均有未验证项清单**(本档不重复) | 档案 104 §九 · 106 §九 · 107 §六 · 109 第三部分 |
| 5 | ⛔ 「平台已有 / 已存在」**未被核实前不得作安全假设** | 本档 §二 自检要求 |
## 三、范围
- **改什么**:⏳ 未开跑。本档为**补遗 + 参考方案 + 反模式**,不含实施。
- **不动什么**:⛔ 不重复各档案已有内容(见 §四 表格);⛔ 本轮不动服务器、不改代码。
- **统一记录格式**(本档所有补遗项按此):**分类 / 结论 / 依据 / 待验证点 / 若做需要什么**。
## 四、决策点
**已定**
1. **互联游戏 ✅ 支持,但由游戏形态决定**:回合制/卡牌/桌游/异步 ✅非常合适;小规模实时合作(≤8–16 人)✅合适;大厅在服务器 + 对局 P2P ✅经典;**大规模强实时竞技(FPS/MOBA 64+)❌不合适**(需专用服务端 + 中继多一跳 + P2P 无法反作弊)。
2. **给覆盖网络的第一建议:优先做「只传输入」的锁步/回合制**(带宽可忽略、延迟容忍度高);实时动作类必须限定在同区域。
3. **⛔ P2P 无法防作弊** ⇒ 凡有竞技性就必须**服务端权威**(好消息:有公网 IP 的节点天然可当对局主机/专用服务端 —— 与骨干层天然衔接)。
4. **⭐ 复用「房间」抽象**:群聊房间与游戏对局是**同一个模型**(成员/可见性/事件分发/离线补拉)⇒ 一次投资四处共用。
5. **落地优先级(补遗之后按依赖排)**:① 房间层 ② 身份与密钥 ③ **会合/中继拆成独立组件**(老结论,仍是第一件实事)④ IPv6 优先 + 上线自检 + 路径决策日志 ⑤ 配额与优先级队列 ⑥ 备份改造 ⑦ 游戏(锁步/回合制先行)。
6. **反模式 12 条为硬拦项**:建全互联 · 无扇出限制的 gossip · 客户端持有权威状态 · 控制面下发全网名单 · 单中心中继当唯一通道 · 网内副本当主备份 · 用慢链路做备份/迁移 · 失败即重试 · agent 直接触发 agent · 推送式分发 · 共享密钥当节点身份 · 只按 IPv4 NAT 设计。
**未定**:本环境 IPv6 可用度(决定能否吃到「直达」红利,**未实测**)。
## 五、步骤
**本档为补遗,实施步骤已被下列档案承担**:
- 房间层 → **档案 108 §五 第 2 步**(组队/行会/频道)
- 身份与密钥 → **档案 112 §9**(协议治理同批)与 **110 §D**(一机一钥)
- 会合/中继拆组件 → **档案 105 §五 第 1 步**(本线第一件实事,见 `接续入口 §2.5`)
- IPv6 / 上线自检 / 决策日志 → **档案 109 §1.4**(数值依据)与 **112 §4**(jitter 选路)
- 配额与优先级队列 → **档案 112 §5**(备份抖动窗口 + 低优先级队列)
- 备份改造 → **档案 110 §B**
- 游戏 → **档案 108 §五**(锁步/回合制先行)
## 六、验收
| # | 口径 | 期望 |
|---|---|---|
| A | 补遗 24 条 | 每条有归属能力域,且**不与既有档案重复** |
| B | 参考方案对照 | 10 个能力域各给出可借鉴的现成物与「借什么」 |
| C | 反模式 12 条 | 逐条可对照,且**每条都指向一个具体后果** |
| D | 落地优先级 | 7 条按**依赖**排(不是按收益) |
| E | 未验证项透明 | §六 四条已列全 |
## 七、回滚
- **本档自身**:零改动 ⇒ 无回滚需要。
- **执行期**:所引用的各档案步骤各自独立可回滚;⛔ **「客户端持有权威状态」不可回滚**(红线,见 §四 第 3 条)。
## 八、回报格式
执行会话回填:① 补遗 24 条中实际被采纳的条数与落点 ② 参考方案的选用结果(谁被选中、为什么) ③ 反模式自查结果(逐条对照,命中项与处置) ④ commit ⑤ 未完成项与卡点。
## 九、未验证项(勿当结论)
本环境 IPv6 可用度(决定能否吃到「直达」红利,**未实测**)|移动端休眠唤醒后的实际重连耗时(**未实测**)|WebRTC DataChannel 经我们中继的延迟与丢包表现(**未实测**)|FEC / 多路径的实际收益(**待评估**)。
---
## 附录 A · 原始规划正文(逐字保留 · 2026-09-16)
> 以下为工作区根 `覆盖网络_补遗与参考方案_20260916.md` 的**原文全文**,仅删除其一级标题(避免与档案标题重复),
> 其余**一字未改**;本档的可判定部分以上方 8 段为准。
> 日期:2026-09-16 | 性质:**补遗复盘**(承接 `覆盖网络_全球架构复盘_20260916.md` 与 `覆盖网络_答疑_群聊备份迁移保密_20260916.md`)
> 🟢 范围:只考虑技术实现;跨境数据合规由使用者自行考虑。
---
## 一、互联游戏:✅ 支持,但**由游戏形态决定**
覆盖网络对游戏是"够用"的底座,**但它是所有应用场景里最"重"的一个** —— 实时性、状态一致性、反作弊三条同时压上来。所以先分类:
| 游戏类型 | 覆盖网络可行性 | 关键约束 |
|---|---|---|
| 回合制 / 卡牌 / 桌游 / 异步 | ✅ **非常合适** | 带宽极小(只传输入),延迟不敏感 |
| 小规模实时合作(≤8–16 人) | ✅ 合适 | 需要主机或专用服务端之一 |
| 大厅在服务器 + 对局 P2P | ✅ 经典架构 | 匹配/排行在中心,对局在 P2P |
| 大规模强实时竞技(FPS/MOBA 64+) | ❌ **不合适** | 需专用服务端 + 权威模拟;中继多一跳;P2P 无法反作弊 |
| 需要严格反作弊的竞技类 | ❌ **P2P 的致命伤** | **客户端持有权威状态 = 可作弊**,必须服务端权威 |
### 1.1 三种同步模型(带宽与延迟特性完全不同)
| 模型 | 传什么 | 带宽 | 适合 |
|---|---|---|---|
| **状态同步** | 定期广播状态快照 + 客户端插值 | 高(随人数上升) | 动作类、小规模 |
| **锁步 / 帧同步** | **只传输入(命令)** | **极低** | RTS、回合、卡牌 —— **对覆盖网络最友好** |
| **回滚码(GGPO 式)** | 输入 + 确定性模拟 + 预测回滚 | 低但要求严格 | 格斗类;**对延迟最敏感,跨洲不可行** |
⇒ **给覆盖网络的第一建议:优先做"只传输入"的锁步/回合制**,带宽可忽略、延迟容忍度高;实时动作类必须限定在同区域。
### 1.2 延迟预算(决定哪些能玩)
| 路径 | 典型 RTT | 可承载 |
|---|---|---|
| 同区域直连 | 5–30 ms | 几乎任何类型 |
| **经中继(多一跳)** | +RTT×2 | 回合/锁步仍可;动作类吃力 |
| 跨洲 | ~200 ms | **只适合回合制/异步** |
### 1.3 游戏特有的风暴点(比聊天更危险)
1. **状态广播放大**:每帧每人发给全体 = O(N²) ⇒ 必须**主机聚合后再分发**,或按**兴趣区域(AOI)裁剪**。
> 📄 **重点修正(2026-09-16 10:0x)**:用户明确游戏重点是 **MMORPG(2D/2.5D)· MUD · 传奇类** —— 这三类是**覆盖网络最匹配的应用**(天生服务端权威 + tick 驱动 + **AOI 九宫格广播** + 分区/分线扩展,每玩家仅数 KB/s~数十 KB/s,几百 ms 延迟无感)。本节上面那张"❌ 不合适"的表**只适用于 3D 大世界强实时竞技**。游戏专项见 **`覆盖网络_游戏专项_MMORPG与MUD_20260916.md`**。
⭐ 该专稿的核心简化:**这类游戏玩家之间不需要互联**(服务端权威,玩家只与游戏服通信)⇒ 覆盖网络只需解决"**让玩家到达游戏服**",**中继容量按"服数"算、不按"玩家数"算**。
2. **输入风暴**:锁步必须限帧率 + 合并输入,不能"每动一下发一条"。
3. **主机切换惊群**:房主掉线时全员抢当主机 ⇒ **必须确定性继任顺序 + 退避**(不能"谁先喊谁当")。
4. **匹配/大厅风暴**:开房高峰的列表刷新 ⇒ 列表走**带 TTL 的拉取**,不做推送。
### 1.4 反作弊(决定架构,不是可选)
**P2P 无法防作弊** ⇒ 只要游戏有竞技性,就必须 **服务端权威**。好消息:覆盖网络里"**有公网 IP 的节点**"天然可当对局主机/专用服务端 —— 与骨干层设计天然衔接。
### 1.5 技术选型与复用点
- 传输:**WebRTC DataChannel 的"不可靠 + 无序"模式**(类 UDP,适合状态流);或直接用覆盖网络的 UDP 隧道。WebRTC 自带 ICE(打洞)+ TURN(中继)兜底,与我们的中继设计同构。
- ⭐ **可复用"房间"抽象**:**群聊房间与游戏对局是同一个模型** —— 成员 / 可见性 / 事件分发 / 离线补拉。一旦建了房间层,**群聊、游戏、协作编辑、看板共用一次投资**。这是本方案最划算的一处架构复用。
---
## 二、补遗清单(按主题;凡前面没写到的都在这)
### 2.1 身份与账户(**最容易被漏,且漏了会出运维灾难**)
1. **多设备同账号**:一个用户多台设备如何归属同一身份;设备加入/移除流程。
2. **密钥丢失的重建路径** ⚠️:私钥丢 = 设备永久失去身份。必须有**恢复机制**(恢复码 / 管理员重签 / 设备转让),且要能撤销被盗设备。
3. **密钥存放**:用系统密钥库(Windows DPAPI / macOS Keychain / Linux TPM),不要明文落盘。
4. **账户与设备的绑定粒度**:设备级身份 + 用户级授权(两层),避免"一台设备泄露 = 整个账号沦陷"。
### 2.2 寻址与名字(没有它,用户只能记 IP)
5. **稳定名字解析**(MagicDNS 式):`<设备>.<用户>.<域名>`;平台已有 `alotbuy.com`,可直接做子域解析。
6. **IPv6 优先** ⚠️ **重要且常被忽略**:不少网络有 IPv6 直达能力 ⇒ **可跳过打洞直接连**。别只按 IPv4 NAT 设计,否则白丢一大块性能红利。
### 2.3 接入与可见性
7. **出口节点 / 子网路由**:把某台机器背后的**整个局域网**借进覆盖网络(访问家里的 NAS、打印机)—— 对"一个人的多设备"场景是关键能力。
8. **服务暴露**:把实例或某端口按**网内可见 / 公网可见**两档暴露(对应 Serve / Funnel 的区分)。
9. **ACL 的具体形态**:粒度(用户 / 设备 / 服务 / 端口 / 时间)、表达方式(策略语言)、下发与缓存、**默认拒绝**。
### 2.4 自检与选路
10. **上线自检**(netcheck 式):探测 UDP 是否被封、NAT 类型、到各区域中继的时延 ⇒ 再决定选路。
11. **路径决策可解释**:每次连接"为什么走了中继"要能查出原因(打洞失败?UDP 被封?策略强制?)—— 排障只能靠这个。
12. **节点健康自评**:打洞率 / 丢包 / 时延 → 主动换路径或换骨干。
### 2.5 流量与公平
13. **按用户/设备配额**(带宽与连接数),防单点占满。
14. **交互流量优先于后台流量**:备份/同步这类用**低优先级队列**(fq_codel / LEDBAT 类),保证聊天与游戏不被备份堵死。
15. **多路径**:直连 + 中继同时传,聚合吞吐(大文件迁移用)。
16. **前向纠错(FEC)**:丢包高的移动网,FEC 比"重传"便宜得多。
### 2.6 移动端与弱网(独立一章,坑最多)
17. **电量**:心跳频率要能与电量/前台状态联动(后台降频)。
18. **系统休眠/冻结**:唤醒后必须**秒级重连**,不能等下一个心跳周期。
19. **网络切换**:Wi-Fi ↔ 蜂窝切换会换 IP ⇒ 需**连接迁移**(QUIC 的 connection migration 就是为这个设计的)。
### 2.7 升级、版本与自愈
20. **协议版本协商**:客户端与平台必须能协商协议版本,**严格递增防降级**。
21. **灰度与回滚**:按节点分批升级,出问题能退回上一版。
22. **更新包签名校验**(防投毒)。
### 2.8 可观测
23. **集中指标 + 每节点画像**(路径类型 / 打洞率 / 时延 / 重连次数)。
24. **可 grep 的决策日志**("为什么走中继")—— 与 12 配套。
---
## 三、参考方案对照(可直接借鉴的现成物)
| 能力域 | 参考方案 | 借什么 |
|---|---|---|
| 组网 / 打洞 / 中继 | **Tailscale / headscale + derper**、NetBird、Nebula、ZeroTier、EasyTier、innernet | 控制面/数据面分离;先中继后直连;限额中继;区域 DERP |
| 打洞 / 中继库 | **libp2p**(DCUtR + relay v2)、**Pion**(Go WebRTC)、**coturn** | 直接可用的协议实现与默认限流参数 |
| 游戏网络 | **GGPO / 回滚码**、**Nakama**(开源游戏后端)、Colyseus、Photon、**WebRTC DataChannel** | 房间/匹配/状态同步的现成模型;不可靠传输 |
| 联机传输库 | enet / KCP / QUIC | 类 UDP 的低延迟可靠传输 |
| 协作编辑 / CRDT | **Yjs**、Automerge | 无中心也一致的协作模型(适合 P2P 房间) |
| 群聊 / 联邦房间 | **Matrix**(联邦式房间,理念与覆盖网络最接近)、Nostr、Scuttlebutt | 房间、事件图、离线补拉、联邦 |
| 备份 | **restic / Borg**(增量 + 去重 + 加密)、**rclone**(多后端 + 加密)、MinIO | **与我们结论一致**:去重 + 客户端加密 + 不可变 |
| 迁移 | rsync(块级增量)、rclone、对象存储中转 | 断点续传与增量 |
| 观测 | Prometheus + Grafana(libp2p 有现成面板)、集中日志 | 直接抄面板 |
| 全球就近 | GeoDNS(PowerDNS / Route53)、anycast、DERP 的区域模型 | 就近接入 |
---
## 四、反模式清单(踩了就出事,逐条对照)
| # | 反模式 | 后果 |
|---|---|---|
| 1 | **建全互联**(N² 保活) | 保活与连接数爆炸 |
| 2 | **无扇出限制的 gossip / 广播** | 泛洪风暴 |
| 3 | **客户端持有权威状态** | 可作弊、可伪造归属 |
| 4 | **控制面下发全网名单** | 元数据全暴露 + 每条连接都要维护 |
| 5 | **单中心中继当唯一通道** | 单点 + 带宽瓶颈 |
| 6 | **把网内副本当主备份** | 无 SLA、可误删、对端离线即失效 |
| 7 | **用慢链路做备份/迁移通道** | 22 KB/s 量级 ⇒ 不可用 |
| 8 | **失败即重试(无退避/抖动)** | 重试风暴 |
| 9 | **agent 直接触发 agent** | 无限循环消息风暴 |
| 10 | **推送式分发(版本/目录/大资源)** | 冷启动拉取风暴 |
| 11 | **共享密钥当节点身份** | 无法吊销、一泄全通 |
| 12 | **只按 IPv4 NAT 设计** | 白丢 IPv6 直达红利 |
---
## 五、落地优先级(补遗之后,按"依赖"排)
1. **房间层**(一次投资,群聊 + 游戏 + 协作 + 看板共用)。
2. **身份与密钥**(一机一钥 + 恢复机制 + 吊销)—— 大量能力的共同前置。
3. **会合 / 中继拆成独立组件**(老结论,仍是第一件实事)。
4. **IPv6 优先 + 上线自检 + 路径决策日志**(低成本高收益)。
5. **配额与优先级队列**(交互优先,备份让路)。
6. 备份改造(去重 + 客户端加密 + 对象存储主层)。
7. 游戏(锁步/回合制先行,服务端权威留给竞技类)。
---
## 六、未验证项
| # | 项 | 状态 |
|---|---|---|
| 1 | 本环境 IPv6 可用度(决定能否吃到"直达"红利) | ⚠️ 未实测 |
| 2 | 移动端休眠唤醒后的实际重连耗时 | ⚠️ 未实测 |
| 3 | WebRTC DataChannel 经我们中继的延迟与丢包表现 | ⚠️ 未实测 |
| 4 | FEC / 多路径的实际收益 | 📋 待评估 |
@@ -0,0 +1,281 @@
# 112 · 覆盖网络 · 九大瓶颈落地方案
- 日期:2026-09-16 | 状态:📋 **规划态 / 未实施**(落地解决方案稿)
- 来源:工作区根 `覆盖网络_瓶颈落地方案_20260916.md`(正文见 附录 A)
- 层级:专项落地(**瓶颈 → 可执行做法**)| 承接档案 **107 §4**(瓶颈排序);被 104 §8 落地顺序引用
- 参考来源:Slack 官方 API 文档 · Microsoft SCCM / BranchCache / Delivery Optimization 官方文档 · presence 系统工程实践
- 🟢 范围:只考虑技术实现;跨境数据合规由使用者自行考虑。
> **TL;DR**
> 把 107 §4 排出的**九大瓶颈**逐个给成**可执行做法 + 验收判据**(含 Slack / SCCM 官方照抄点)。
> 🎯 **如果只做三件事:presence 改造 + 游戏服放 L1 + 块级内容寻址分发** —— 覆盖最大的三个瓶颈,且**都不需要改传输协议**。
> 🔑 两个"零成本/低成本高收益"点:**游戏服部署规范(零成本,直接消掉 600 Mbps)**;**presence 改造(唯一第一瓶颈,纯应用层,不动协议)**。
## 一、目标
把九大瓶颈(presence / 游戏服放家宽 / 首屏包冷启动 / 中继抖动 / 备份窗口挤占 / 重连风暴 / agent 自激 / NAT 表溢出 / 版本碎片)逐条转成**可执行做法 + 验收判据 + 成本评级**。
可判定「做完了没有」= 九条齐备,且**每条都有可复现的验收判据**(不是"感觉好了")。
## 二、只读前置
| # | 事实 | 核对方式(期望输出) |
|---|---|---|
| 1 | 首屏包 **10.8 GB/次**(1000 台口径)是 #3 的量级来源 | 实测 `11,363,655 B` × 1000(档案 97 / 107 §0.3) |
| 2 | 游戏服放家宽 ⇒ 中继需要 **600 Mbps 常驻** | 档案 107 §S3(300 × 10 KB/s = 24 Mbps/服 × 25 服) |
| 3 | presence 是 1000 台下的**第一瓶颈**(8.2k–16.7k 次/秒) | 档案 107 §S2 / §3 / §4 |
| 4 | 平台已有 **ETag / 304 短路**能力(内容分发的现成基础) | 档案 97 |
| 5 | 平台已有**崩溃熔断 + 冷却**先例(#6 重连治理可复用同一套机制) | 档案 78 |
## 三、范围
- **改什么**:⏳ 未开跑。方案面 = presence 应用层改造 · 游戏服部署规范 · 内容分发三件套 · 中继抖动选路 · 备份窗口治理 · 重连治理 · agent 硬约束 · 每子网打洞并发上限 · 协议版本治理。
- **不动什么**:⛔ 官方 dsh 主程序(R2)|⛔ **不改传输协议**("只做三件事"的硬前提)|⛔ 本轮不动服务器、不改代码。
## 四、决策点
**已定**
1. **🎯 只做三件事 = presence 改造 + 游戏服放 L1 + 块级内容寻址分发**(覆盖最大三个瓶颈,且都不需要改传输协议)。
2. **游戏服部署规范 = 游戏服一律部署在有公网 IP 的节点上**(零成本,收益最大)⇒ 服主在 NAT 后时**主动拨出到骨干、玩家连骨干入口**(不是直连服主)。
3. **必须做「块级 + 内容寻址」,⛔ 不要做「包级」** —— 包级(Peer Cache 式)的坑:必须完整下载完才能当 peer 源,版本一变所有 peer 源失效 ⇒ **这正是「版本一发就全量重拉」的风暴成因**。
4. **✅ 用户已定:presence 改造走 Slack 官方做法**(`presence_sub` + `batch_presence_aware`:订阅式扇出 + 只推给"正在看的人" + 本地批合并 + 绑连接生命周期)。
5. **⛔ 禁止 agent 直接触发 agent**(只有人的消息能触发)—— 唯一能真正切断指数增长的规则。
6. **明确使用最终一致**(presence 允许 5–15 s 陈旧;⛔ **不要为 presence 上强一致**)。
7. **落地顺序按「收益 ÷ 成本」排**(见 §五)。
**未定**:agent 限额参数(M / N / 房间上限)取值 —— **需压测标定**。
## 五、步骤(§落地顺序,按「收益 ÷ 成本」;每步自带一次验证)
1. **presence 改造**(七条落地做法)→ 验证:1000 人大房广播**从 ~16,700/s 降到 <2,000/s**;进房间首屏 presence **一次 bulk 请求**完成(无 N+1)。
2. **游戏服部署规范(放 L1)** → 验证:新开服默认落 L1;中继出口带宽与"服数"的关系**可预测**。
3. **内容分发:块级内容寻址 + 同网段 peer**(一次投资治 #3、#5、#9)→ 验证:版本发布时回源字节数 ≈ **1 份 × 组数**(不是 1000 份)。
4. **重连治理**(指数退避 + 全抖动 + 重试预算 + 令牌桶)→ 验证:拔掉一台中继后 1000 台重连曲线**平滑爬升**,不是尖峰。
5. **备份抖动窗口 + 低优先级队列** → 验证:备份进行期间聊天与游戏的 **p95 延迟不变**。
6. **jitter 度量与选路**(按 jitter 排序,**不按 RTT 排序**;中继侧 fq_codel/SQM)→ 验证:每连接 jitter 直方图;超阈值自动切路径并告警。
7. **agent 配额 + 硬约束** → 验证:注入「回声型 agent」压测,房间消息量**有上限、不增长**。
8. **每子网打洞并发上限 + 收敛探测** → 验证:同一办公室 **20 台同时上线**,NAT 不丢线、其他网络不受影响。
9. **协议版本治理**(协商 + 灰度 1%→10%→100% + 相邻版本互通 + 内容寻址版本包)→ 验证:各版本节点数与错误率**按版本切分**可观测。
## 六、验收
| # | 口径 | 期望 |
|---|---|---|
| A | 九条各有判据 | 每条给出「可复现的验收判据」(本档各节末「验收判据」) |
| B | presence | <2,000/s(原 ~16,700/s);首屏 presence 一次 bulk |
| C | 游戏 | 新开服默认落 L1;中继出口带宽与服数**可预测**(不随玩家数漂移) |
| D | 内容分发 | 回源字节 ≈ 1 份 × 组数;局域网内多台设备只回源一次 |
| E | 中继 | 利用率留 **30%+ 余量**;每连接 jitter 直方图可观测 |
| F | 备份 | 备份期间交互流量 p95 延迟不变 |
| G | agent | 回声型 agent 压测下消息量有上限 |
| H | 未验证项透明 | §未验证项 五条已列全 |
## 七、回滚
- **本档自身**:零改动 ⇒ 无回滚需要。
- **执行期**:九步各自独立可回滚(均为应用层参数/规范/开关,**不涉及传输协议变更**)⇒ 回滚即还原参数。
- ⚠️ 第 3 步(内容分发)与第 9 步(版本包)**共用一套分发机制** ⇒ 回滚须成对评估。
## 八、回报格式
执行会话回填:① 每步验证命令 + 实际输出(**必须含本档各节的验收判据**) ② presence 收敛实际降幅 ③ 同网段 peer 命中率 ④ fq_codel 实际效果 ⑤ agent 限额参数标定值 ⑥ commit ⑦ 未完成项与卡点。
## 九、未验证项(勿当结论)
presence 收敛的实际降幅(业界口径可达 **5×–8×**,**需实测**)|中继链路的 **jitter 分布**(决定能否支撑游戏,**最该先测**)|同网段 peer 命中率(决定 10.8 GB 能压到多少,**需实测**)|**fq_codel 在本环境中继上的实际效果**(需实测)|agent 限额参数(M / N / 房间上限)取值(**需压测标定**)。
---
## 附录 A · 原始规划正文(逐字保留 · 2026-09-16)
> 以下为工作区根 `覆盖网络_瓶颈落地方案_20260916.md` 的**原文全文**,仅删除其一级标题(避免与档案标题重复),
> 其余**一字未改**;本档的可判定部分以上方 8 段为准。
> 日期:2026-09-16 | 性质:**落地解决方案**(承接 `覆盖网络_千台全场景推演_20260916.md` 的瓶颈排序)
> 参考来源:Slack 官方 API 文档、Microsoft SCCM / BranchCache / Delivery Optimization 官方文档、presence 系统工程实践(详见各节"参考实现")
> 🟢 范围:只考虑技术实现;跨境数据合规由使用者自行考虑。
---
## 总览:九个瓶颈 × 落地手段
| # | 瓶颈 | 量级 | 核心手段 | 成本 |
|---|---|---|---|---|
| 1 | **presence** | 8.2k–16.7k 次/秒 | **订阅式扇出 + 本地批合并 + 绑连接生命周期** | 低(纯应用层) |
| 2 | **游戏服放家宽** | 600 Mbps 常驻 | **部署规范:游戏服一律放有公网 IP 的节点** | **零** |
| 3 | **首屏包冷启动** | 10.8 GB/次 | **块级内容寻址 + 同网段 peer 优先** | 中 |
| 4 | **中继抖动** | 需 <20 ms | **按抖动选路 + 中继限载 + fq_codel** | 中 |
| 5 | 备份窗口挤占 | 136 Mbps | **抖动窗口 + 低优先级队列** | 低 |
| 6 | 重连风暴 | 160 / 1000 并发 | **全抖动退避 + 重试预算 + 令牌桶** | 低 |
| 7 | agent 自激 | 指数级 | **禁止 agent 触发 agent + 独立配额** | 低 |
| 8 | NAT 表溢出 | 整屋掉线 | **每子网打洞并发上限 + 收敛探测** | 低 |
| 9 | 版本碎片 | — | **协议协商 + 灰度 + 内容寻址版本包** | 中 |
---
## 1. presence(最高优先,收益/成本比最好)
### 落地做法(七条,均有成熟先例)
1. **presence 绑到连接生命周期,不要轮询** —— WebSocket 连上 = 在线、断开 = 离线;**存储带 TTL 只作安全网**(防网关崩溃漏事件)。彻底干掉"每 30 s 全员轮询"。
2. **本地批合并 + pipeline 刷写** —— 每个网关把本地心跳攒起来,**每 1 s 一次 pipeline 提交**。
业界的量级对照:10 万连接 × 0.2 心跳/s = **2 万条命令/秒** ⇒ 合并后变成 **1 次 pipeline/秒**(数量级差异)。
3. **订阅式扇出:只推给"正在看的人"** —— 用户打开某个聊天/名单才订阅该用户的 presence,**订阅只活在连接期间**。
这是 **Slack 官方做法**(`presence_sub` + `batch_presence_aware`),也是它们把 presence 流量降下来的关键。
4. **批量事件 + 节流** —— 一条消息里带 **user 数组**(不是逐个 user);**最多每几秒推一批**。
5. **grace period 5–15 s + 离线 debounce 30 s** —— 防止"网络抖一下 = 状态闪烁",把短暂断连合并掉。
6. **多设备按 device 聚合** —— 任一设备在线即在线;**重连后必须重新拉一次全量**(否则状态陈旧)。
7. **明确使用最终一致** —— 允许 5–15 s 陈旧。⛔ **不要为 presence 上强一致**(会毁掉吞吐,且业务上不需要)。
### 大房(≥1000 人)的特殊策略
- 只推 **在线 / 离线**(不推 idle、不推 typing);**按百分比抽样降频**(如每 10 s 一轮);
- 打开房间用 **一次 bulk 查询**拿全量,之后只增量。
### 参考实现
Slack 官方 changelog(batch presence + presence subscriptions)、Redis TTL + pub/sub 的 presence 标准设计、WebSocket 生命周期作为 presence 信号。
### 验收判据
- 1000 人大房的 presence 广播次数 **从 ~16,700/s 降到 <2,000/s**;
- 进房间首屏 presence **一次 bulk 请求**完成(无 N+1)。
---
## 2. 游戏服放哪(**零成本,收益最大**)
### 落地做法
1. **部署规范:游戏服一律部署在有公网 IP 的节点上**(= 骨干层)⇒ 玩家直连,**中继承载 0**。
2. 服主确实在 NAT 后时:**服主动拨出到骨干**,**玩家连骨干入口**(不是直连服主)—— 把中继点从"服主机器"搬到"骨干",并让骨干做流量聚合。
3. **错峰 + 配额**:攻城战高峰用**按服限额**,并提前公告时段。
4. 容量按 **45% 设计、55% 留余量**;骨干池 **≥ N+1**。
### 验收判据
- 新开服默认落 L1;
- **中继出口带宽与"服数"的关系可预测**(而不是随玩家数漂移)。
---
## 3. 首屏包冷启动(10.8 GB)—— 照抄内容分发三件套
### 落地做法(**直接照搬 SCCM 的内容源优先级**)
1. **内容源优先级**(改成我们的版本):
**本地磁盘 → 同局域网 peer → 同区域边缘缓存 → 区域分发点 → 公网源**
(原版优先级顺序见 Microsoft 官方文档,结构一致)
2. **必须做"块级 + 内容寻址",不要做"包级"** —— 这是 **BranchCache vs Peer Cache** 的关键分水岭:
- **块级(BranchCache 式)**:按**哈希标识块**、**与文件无关** ⇒ **只拿到一部分也能开始共享**;内容更新时**只传变化的块**;
- ⚠️ **包级(Peer Cache 式)的坑**:必须**完整下载完**才能作为 peer 源;**版本一变所有 peer 源全部失效**,客户端会集体回源 ⇒ **这正是"版本一发就全量重拉"的风暴成因**。
3. **客户端校验哈希**,不匹配就丢弃(Delivery Optimization 的做法)。
4. **分组**:按"用户 / 团队 / 局域网"分组共享(对应 DO 的 group mode),避免跨组乱穿透。
5. **同网段优先广播发现**(BranchCache 在子网内广播哈希找 peer)。
6. 已加载走 **304**(平台已有此能力)。
### 验收判据
**版本发布时回源字节数 ≈ 1 份 × 组数**(而不是 1000 份);局域网内多台设备只回源一次。
---
## 4. 中继抖动(游戏可玩性的真正门槛)
### 落地做法
1. **把 jitter 做成一等指标** —— 持续采样 RTT 与 **jitter(RTT 方差)**,**选路按 jitter 排序,不按 RTT 排序**。
2. **抑制 bufferbloat** —— 中继侧启用 **fq_codel / SQM** 类队列管理;排队延迟是抖动最大的来源。
3. **路径多样性** —— 每连接维护 2–3 条候选(直连 / 就近中继 / 备用中继),**抖动劣化即切**。
4. **中继不要打满** —— 利用率留 **30%+ 余量**;打满必然抖动爆炸。
5. **就近接入** —— 骨干用 BGP 多线 / 就近节点(业界口径:BGP 多线可把跨网延迟压到 20 ms 内)。
### 验收判据
每连接的 **jitter 直方图**;超阈值自动切路径并告警。
---
## 5. 备份窗口挤占
1. **抖动窗口**:200 台备份起点**随机散布到 2–3 小时**(cron + 随机 sleep),把 136 Mbps 尖峰摊平。
2. **低优先级队列**:备份/同步走 **background 类**(fq_codel 的 background 档,或 LEDBAT 式延迟敏感型拥塞控制)⇒ 交互流量优先。
3. **双层限速**:每台上限 + 全网上限。
4. **只备不可再生 + 增量去重 + 上传前加密**(沿用备份三层方案)。
5. 上传走**各自到对象存储**的路径,**不走中继**。
### 验收判据
备份进行期间,聊天与游戏的 **p95 延迟不变**。
---
## 6. 重连风暴(160 / 1000 并发)
1. **指数退避 + 全抖动(full jitter)** —— 关键结论:**没有抖动,退避会同步化**,等于没退。
2. **重试预算(retry budget)** —— 限制"重试流量 / 正常流量"比例(如 10%),超预算就停止重试。
3. **控制面令牌桶 + 排队 + 明确的 429/Retry-After**。
4. **数据面不依赖控制面** —— 已建立的连接在控制面重启时不受影响。
5. **熔断 + 冷却**(平台已有崩溃熔断先例,可复用同一套机制)。
### 验收判据
拔掉一台中继后,1000 台的重连曲线是**平滑爬升**,不是**尖峰**。
---
## 7. agent 自激(本方案独有的放大源)
1. **禁止 agent 直接触发 agent** —— **只有人的消息能触发 agent 发言**。这是唯一能真正切断指数增长的规则。
2. 每 agent **每 N 分钟最多 M 条** + 发言后**静默期**。
3. **房间级 agent 数上限**(建议 ≤ 房间人数 / 10)+ 房间级总速率上限。
4. **agent 独立配额池**(不与人共享额度,避免 agent 挤掉真人)。
5. 观测:**agent 发言占比**告警。
### 验收判据
注入一个"回声型 agent"做压测,**房间消息量有上限、不增长**。
---
## 8. NAT 表溢出
1. **每 NAT / 每子网的打洞并发上限**(按该 NAT 的会话数能力推算)。
2. **收敛探测** —— 禁止所有设备同时打同一目标;加**随机延迟 + 指数退避**。
3. **同网段优先本地发现**(mDNS 式)⇒ 压根不走 NAT。
4. 打洞失败**即降级中继**,不重试(与 #6 共用机制)。
### 验收判据
同一办公室 **20 台同时上线**,NAT 不丢线、其他网络不受影响。
---
## 9. 版本碎片
1. **协议版本协商 + 严格递增**(防降级攻击)。
2. **灰度**:1% → 10% → 100% 分批。
3. **相邻版本必须互通**(客户端 N 与 N-1 必须能对话)。
4. **版本包走内容寻址**(与 #3 共用一套分发机制)。
5. 观测:各版本节点数与错误率**按版本切分**。
---
## 落地顺序(按"收益 ÷ 成本"排)
| 序 | 动作 | 为什么排这里 |
|---|---|---|
| 1 | **presence 改造** | 唯一的第一瓶颈,且是**纯应用层**改动,不动协议 |
| 2 | **游戏服部署规范**(放 L1) | **零成本**,直接消掉 600 Mbps |
| 3 | **内容分发:块级内容寻址 + 同网段 peer** | 一次投资同时治 #3、#5、#9 |
| 4 | **重连治理**(退避 + 全抖动 + 重试预算 + 令牌桶) | 低成本,防事故 |
| 5 | **备份抖动窗口 + 低优先级队列** | 低成本 |
| 6 | **jitter 度量与选路** | 决定游戏可玩性 |
| 7 | **agent 配额 + 硬约束** | 本方案独有风险 |
| 8 | **每子网打洞并发上限** | 低成本 |
| 9 | **协议版本治理** | 随规模推进 |
### 如果只做三件事
**presence 改造 + 游戏服放 L1 + 块级内容寻址分发** —— 这三件覆盖了最大的三个瓶颈,且**都不需要改传输协议**。
---
## 未验证项
| # | 项 | 状态 |
|---|---|---|
| 1 | presence 收敛的实际降幅(业界口径可达 5×–8×) | ⚠️ 需实测 |
| 2 | 中继链路的 jitter 分布(决定能否支撑游戏) | ⚠️ **最该先测** |
| 3 | 同网段 peer 命中率(决定 10.8 GB 能压到多少) | ⚠️ 需实测 |
| 4 | fq_codel 在本环境中继上的实际效果 | ⚠️ 需实测 |
| 5 | agent 限额参数(M / N / 房间上限)取值 | 📋 需压测标定 |
+10
View File
@@ -148,6 +148,16 @@
| 06 | 🔄 | **前端 UI 强制基线**:Token/布局/组件/交互/9 条已知坑 |
| 07 | ✅ | **实例 UI 分区登记表**:settings.section 的 id/order/label → 提供者 → 源码 → 可改性 + 定位套路(含"中文文案要同时搜 UTF-8 与 \uXXXX") |
| 04-89 | 🔄 进行中(L2 机制级已验 | **对话内文件预览**:采纳官方推荐库现成插件 `@softspark/dsh-file-preview`(65 KB,包住官方 `openWorkspacePath` 接管"点文件"手势;兼容预检 ok、已启用、L5 |
| 04-103 | 📋 | **客户端安装 + 覆盖网络互联 · 可行性评估**(规划态 · 未实施):判定 ✅ 可行,且现有架构已给出约 80% 形状(`soft` 档实例=裸子进程 ⇒ 无需 root;Worker 拨出式反向隧道 ⇒ **节点本来就不需要公网 IP**);缺口 4 条(客户端运行时落点 · 节点身份 · **信任模型反转** · 分发与版本矩阵);形态三档已按用户口径收窄为**单机自用**(B 档);6 步落地、每步可单独回滚。⚠️ 真正硬阻塞点修正 = **平台调用层**(Windows 下裸名 `spawn` ENOENT / `.cmd` EINVAL),非 dsh 运行时 |
| 04-104 | 📋 | **覆盖网络 · 全球架构复盘**(规划态 · 未实施):五层架构(控制面 / 会合 / 骨干·中继 / 数据面 / 观测)+ 12 条必须内建特性 + **10 类风暴类型学** + 流量组织五原则 + 流量预算表 + 7 步落地顺序。🔑 三句结论:控制面与数据面**彻底分离** · 失败不要变成重试(退避+抖动+判死) · 放大点必须前置治理。🟢 范围声明:**只做技术实现,跨境数据合规由使用者自负**(⛔ 不再作前置条件或上抛项) |
| 04-105 | 📋 | **覆盖网络 · 骨干层方案**(规划态 · 未实施):多中心骨干(≤10–20 成员、全互联;每节点只连 1–2 个骨干)+ 选择性加入。三条硬约束:**接入 / 成员 / 可见三分离** · **骨干资格只能控制面签发**(否则出现第二权威源、骨干沦为公网跳板) · **骨干不得被默认征用**(命中 R5)。⚠️ §7 唯一待拍板 = 骨干服务范围(A 只服务自己名下设备 / B 服务全网;**倾向 A→B 渐进**) |
| 04-106 | 📋 | **覆盖网络 · 百台规模推演 v2**(规划态 · 纯文字推演):⚠️ 含**前提级纠错**(v1 作废)—— 用户纠正「**单机用也要互联**」;错因 = **把「租户维度收窄」误当成「网络维度收窄」**。100 台异构画像:L1 10 / L2 30 / **L3 需中继 40–55** ⇒ **中继按 45% 设计、55% 留余量**(⛔ 不用同构假设的 15%);**必须补 443/TCP 兜底**(否则企业/校园网整类进不来);**L1 自动升格为中继候选**;仍不建全互联(4,950 vs 100) |
| 04-107 | 📋 | **覆盖网络 · 千台全场景推演**(规划态 · 纯文字推演):1000 台异构 × 11 场景 + **流量预算总表** + 瓶颈排序。🔥 **第一瓶颈 = presence**(1000 人大房 ≈ **16,700 次/秒**,是其消息扇出的 16 倍;普通房合计 8,200/s);💰 **最大成本杠杆 = 游戏服放 L1**(放家宽 ⇒ 中继 **600 Mbps 常驻**、峰值 1.2–2.0 Gbps;放公网 IP ⇒ **0**);游戏的真正门槛是 **jitter < 20 ms** 而非带宽;**agent 为本方案独有放大源** |
| 04-108 | 📋 | **覆盖网络 · 游戏专项(MMORPG 2D/2.5D · MUD · 传奇类)**(规划态 · 未实施):⚠️ 判定**由「不合适」修正为「最匹配」**(该类游戏天生服务端权威 + tick 驱动 + **AOI 九宫格** + 分区/分线;每玩家仅数 KB/s~数十 KB/s、几百 ms 无感)—— 原"不合适"只针对 3D 大世界强实时竞技。⭐ 核心简化:**玩家之间不需要互联 ⇒ 中继容量按「服数」算、不按「玩家数」算**。含 12 条设计细节 + 参考方案(Evennia/Skynet/Pomelo/Nakama…)+ 8 条反模式 |
| 04-109 | 📋 | **覆盖网络 · 调研:游戏网络特征与单房间群聊上限**(规划态 · 全网调研稿,数值均标来源):游戏侧每玩家 **2–20 KB/s**、同步 5–20 Hz、**jitter > 20 ms 即 desync**;群聊侧 **Telegram 20 万 / WhatsApp 2,048 / Discord 单频道 100K+**;🔑 **上限不是「人数」而是「扇出预算」**,且 **presence(N²) 比消息更早爆**(1000 人房 ≈16,700/s)。**本方案实际上限 = min(扇出预算, presence 预算, agent 预算)** |
| 04-110 | 📋 | **覆盖网络 · 答疑(群聊+agent / 备份 / 迁移提速 / 传输保密)**(规划态 · 未实施):① 群聊=**应用层**的事(覆盖网络只给「可达」);**agent 四条硬约束**(⛔ 禁止 agent 直接触发 agent);② ✅ **备份主层用对象存储**,覆盖网络只当**搬运通道与第三副本**(P2P 副本无 SLA、可误删,不适合当存档);③ 迁移 7 条按收益排,**最大一招 = 只搬不可再生(46.3 MB vs 2.9 GiB ≈ 64×)**;④ 保密 = 三层加密 + 元数据保护,**最大缺口 = 身份(共享令牌 → 一机一钥)** |
| 04-111 | 📋 | **覆盖网络 · 补遗与参考方案**(规划态 · 未实施):互联游戏 ✅ 但**由游戏形态决定**(锁步/回合/异步最友好;FPS/MOBA 64+ ❌ 不合适,P2P 无法反作弊);补遗 **24 条**(身份与账户 / 寻址与名字 / 接入与可见性 / 自检与选路 / 流量与公平 / 移动端弱网 / 升级版本自愈 / 可观测)+ 10 个能力域的参考方案 + **反模式 12 条**。⭐ 最划算的架构复用:**群聊房间与游戏对局是同一个模型**(一次投资,群聊 + 游戏 + 协作 + 看板共用) |
| 04-112 | 📋 | **覆盖网络 · 九大瓶颈落地方案**(规划态 · 未实施):把 107 的九大瓶颈逐个给成**可执行做法 + 验收判据**(含 Slack / SCCM·BranchCache·Delivery Optimization 官方照抄点)。🎯 **只做三件 = presence 改造 + 游戏服放 L1 + 块级内容寻址分发**(覆盖最大三个瓶颈,且**都不需要改传输协议**)。🔑 分水岭:**必须做「块级」内容寻址,⛔ 别做「包级」**(包级 = 版本一发所有 peer 源失效 ⇒ 正是全量重拉风暴的成因) |
| — | 🗄 | `archive/dsh-improvement-plan-20260909-full.md`:拆分前 19 章 |
| — | ✅ | `skills/dsh-change-workflow/SKILL.md`:六阶段 + **红线 R1-R11**(工作副本在本机 `.workbuddy/skills/`)|
| — | ✅ | `skills/dsh-decision-method/SKILL.md`:**改造决策方法论**(用户有效决策 U1-U12 / AI 有效决策 A1-A13 / 反例 X1-X8 + 确认最优解十问 + 交互 UI 专项清单)(工作副本在本机 `.workbuddy/skills/`)|
+173 -22
View File
@@ -1,27 +1,28 @@
{
"generatedFrom": "scripts/docs-manifest.py",
"counts": {
"files": 138,
"chars": 1129912
"files": 148,
"chars": 1222542
},
"tiers": {
"hot": 7,
"cur": 27,
"warm": 56,
"cold": 12,
"warm": 57,
"cold": 21,
"doc": 36
},
"domains": {
"platform": 54,
"method": 28,
"platform": 60,
"method": 29,
"ui": 14,
"plugin": 27,
"ops": 10,
"ops": 11,
"?": 2,
"external": 5
},
"layers": {
"L0": 1,
"L5": 115,
"L5": 125,
"L4": 4,
"L2": 3,
"?": 1,
@@ -65,8 +66,8 @@
"title": "03 路线图与待办",
"status": "?",
"date": "",
"chars": 18493,
"lines": 127,
"chars": 18981,
"lines": 128,
"refs": 0,
"refsCurrent": 0,
"tier": "doc",
@@ -217,7 +218,7 @@
"date": "04-10",
"chars": 6261,
"lines": 129,
"refs": 24,
"refs": 48,
"refsCurrent": 1,
"tier": "cur",
"layer": "L5",
@@ -269,6 +270,111 @@
"domain": "ui",
"tldr": "**结论**:语言切换搬进 **`@dsh-local/portal-entry` 的「用户设置」分区**(id `user-settings`,order 103),"
},
{
"path": "04-调整方案/103-客户端安装与覆盖网络互联-可行性评估.md",
"num": "103",
"title": "103 · 客户端安装与覆盖网络互联 · 可行性评估",
"status": "📋 规划态 / 未实施(本轮",
"date": "2026-09-16",
"chars": 11661,
"lines": 242,
"refs": 0,
"refsCurrent": 0,
"tier": "cold",
"layer": "L5",
"domain": "platform",
"tldr": "> ✅ **可行,且现有架构已给出约 80% 的形状** —— T08 集群化已经把「一台机器 = 一个可被平台拨入的执行体」定义完了,"
},
{
"path": "04-调整方案/104-覆盖网络-全球架构复盘.md",
"num": "104",
"title": "104 · 覆盖网络 · 全球架构复盘",
"status": "📋 规划态 / 未实施(架构",
"date": "2026-09-16",
"chars": 9621,
"lines": 267,
"refs": 0,
"refsCurrent": 0,
"tier": "cold",
"layer": "L5",
"domain": "platform",
"tldr": "> ✅ **有完整可循的工程路径** —— Tailscale / ZeroTier / Nebula / libp2p / BitTorrent 已反复验证过,**关键是照抄它们踩过的坑,而不是自己发明**。"
},
{
"path": "04-调整方案/105-覆盖网络-骨干层方案.md",
"num": "105",
"title": "105 · 覆盖网络 · 骨干层方案",
"status": "📋 规划态 / 未实施(设计",
"date": "2026-09-16",
"chars": 7710,
"lines": 254,
"refs": 0,
"refsCurrent": 0,
"tier": "cold",
"layer": "L5",
"domain": "?",
"tldr": "> ✅ **可以,而且是成熟系统里的标准模式** —— 业内叫「**超级节点 / 骨干层(supernode / backbone)**」(ZeroTier Moon · Nebula Lighthouse · Tailscale DERP"
},
{
"path": "04-调整方案/106-覆盖网络-百台规模推演-v2.md",
"num": "106",
"title": "106 · 覆盖网络 · 百台规模推演-v2",
"status": "📋 规划态",
"date": "2026-09-16",
"chars": 8519,
"lines": 255,
"refs": 0,
"refsCurrent": 0,
"tier": "cold",
"layer": "L5",
"domain": "platform",
"tldr": ""
},
{
"path": "04-调整方案/107-覆盖网络-千台全场景推演.md",
"num": "107",
"title": "107 · 覆盖网络 · 千台全场景推演",
"status": "📋 规划态(文字推演",
"date": "2026-09-16",
"chars": 9463,
"lines": 290,
"refs": 0,
"refsCurrent": 0,
"tier": "cold",
"layer": "L5",
"domain": "?",
"tldr": "> 1000 台异构设备 × 11 个场景的流量推演。**控制面在 1000 台规模仍不是瓶颈**(50 req/s);"
},
{
"path": "04-调整方案/108-覆盖网络-游戏专项-MMORPG与MUD.md",
"num": "108",
"title": "108 · 覆盖网络 · 游戏专项-MMORPG与MUD",
"status": "📋 规划态 / 未实施",
"date": "2026-09-16",
"chars": 7498,
"lines": 231,
"refs": 0,
"refsCurrent": 0,
"tier": "cold",
"layer": "L5",
"domain": "platform",
"tldr": "> 这三类游戏的架构(**服务端权威 + tick 驱动 + AOI 九宫格广播 + 分区/分线**)**本身就是覆盖网络友好型的**,"
},
{
"path": "04-调整方案/109-覆盖网络-调研-游戏网络特征与群聊上限.md",
"num": "109",
"title": "109 · 覆盖网络 · 调研-游戏网络特征与群聊上限",
"status": "📋 规划态(全网调研稿",
"date": "2026-09-16",
"chars": 7347,
"lines": 203,
"refs": 0,
"refsCurrent": 0,
"tier": "cold",
"layer": "L5",
"domain": "platform",
"tldr": "> 两部分:① **这类游戏的网络特征**(传奇 / MMORPG / MUD 的每玩家带宽、同步间隔、承载、延迟/丢包门槛);"
},
{
"path": "04-调整方案/11-技能管理面-shared+mine-API与页面.md",
"num": "11",
@@ -277,13 +383,58 @@
"date": "04-11",
"chars": 7789,
"lines": 176,
"refs": 15,
"refs": 28,
"refsCurrent": 0,
"tier": "warm",
"layer": "L5",
"domain": "method",
"tldr": "**结论**:补完技能管理面:admin 管**全员共享技能** + 每个用户管**自己的个人技能**(`/api/skills/{shared,mine}` + 页面)。"
},
{
"path": "04-调整方案/110-覆盖网络-答疑-群聊备份迁移保密.md",
"num": "110",
"title": "110 · 覆盖网络 · 答疑-群聊备份迁移保密",
"status": "📋 规划态(技术答疑稿",
"date": "2026-09-16",
"chars": 6824,
"lines": 221,
"refs": 0,
"refsCurrent": 0,
"tier": "cold",
"layer": "L5",
"domain": "ops",
"tldr": "> 四问四答:① **群聊 + agent 入群** = ✅ 可实现(群聊是**应用层**的事,覆盖网络只解决「可达」);② **备份** = **主备份优先对象存储**,"
},
{
"path": "04-调整方案/111-覆盖网络-补遗与参考方案.md",
"num": "111",
"title": "111 · 覆盖网络 · 补遗与参考方案",
"status": "📋 规划态(补遗复盘稿",
"date": "2026-09-16",
"chars": 8308,
"lines": 251,
"refs": 0,
"refsCurrent": 0,
"tier": "cold",
"layer": "L5",
"domain": "platform",
"tldr": "> 四部分:① **互联游戏可行性**(✅ 支持,但**由游戏形态决定**;优先做「**只传输入**」的锁步/回合制);"
},
{
"path": "04-调整方案/112-覆盖网络-九大瓶颈落地方案.md",
"num": "112",
"title": "112 · 覆盖网络 · 九大瓶颈落地方案",
"status": "📋 规划态 / 未实施",
"date": "2026-09-16",
"chars": 9158,
"lines": 282,
"refs": 0,
"refsCurrent": 0,
"tier": "cold",
"layer": "L5",
"domain": "method",
"tldr": "> 把 107 §4 排出的**九大瓶颈**逐个给成**可执行做法 + 验收判据**(含 Slack / SCCM 官方照抄点)。"
},
{
"path": "04-调整方案/12-VoxEMW全云API化接入dsh-调研与M1落地.md",
"num": "12",
@@ -1282,7 +1433,7 @@
"date": "2026-09-13",
"chars": 5969,
"lines": 111,
"refs": 9,
"refs": 10,
"refsCurrent": 0,
"tier": "warm",
"layer": "L5",
@@ -1387,9 +1538,9 @@
"date": "2026-09-13",
"chars": 12153,
"lines": 236,
"refs": 0,
"refs": 2,
"refsCurrent": 0,
"tier": "cold",
"tier": "warm",
"layer": "L5",
"domain": "platform",
"tldr": "① 原先平台是「**统一 KEY**」——`resolveApiKey()` **显式忽略入参 userId**,不管谁 spawn 都注入 admin 那一把;② 本轮改为**两层**:**用户自己的 key 优先,没有才回落管理员的「平"
@@ -1567,7 +1718,7 @@
"date": "2026-09-14",
"chars": 3035,
"lines": 76,
"refs": 1,
"refs": 6,
"refsCurrent": 0,
"tier": "warm",
"layer": "L5",
@@ -1700,8 +1851,8 @@
"title": "dsh 平台文档导航(INDEX)",
"status": "?",
"date": "",
"chars": 16649,
"lines": 830,
"chars": 19438,
"lines": 840,
"refs": 0,
"refsCurrent": 0,
"tier": "doc",
@@ -1910,8 +2061,8 @@
"title": "dsh-decision-method — 平台改造的思考与决策方法",
"status": "?",
"date": "",
"chars": 12562,
"lines": 306,
"chars": 14128,
"lines": 335,
"refs": 0,
"refsCurrent": 0,
"tier": "doc",
@@ -2000,8 +2151,8 @@
"title": "dsh-feature-first — 功能优先协作协议",
"status": "?",
"date": "",
"chars": 13242,
"lines": 353,
"chars": 14920,
"lines": 361,
"refs": 0,
"refsCurrent": 0,
"tier": "doc",