Files
dsh_shenxian/dsh-server-docs/04-调整方案/107-覆盖网络-千台全场景推演.md
T
admin 4e3a1a4a13 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> 再写)
2026-09-16 10:25:09 +08:00

290 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 并发重连时控制面 / 中继的实际表现 | ⚠️ 未压测 |