回收 411 MB(470 M → 58.8 M),全部经回收站,可恢复: - 待清理/(146.2 M,含 relay 分片 128 M 与 42 项过程目录) - tmp/(32.4 M,按接续棒命名的过程临时区) - .workbuddy/tmp/(39.5 M) - 4 份 workbuddy.db 冗余副本(101 M,09-23 事故的坏副本 / 抢救产物) - tmp/im16/gw/centrifugo 二进制(63.9 M,可重下)+ 缓存残留 入库范围:常驻规则(CODEBUDDY.md / README.md / state.py)、在途接续入口与 接续包、docs/、交付物/、交接单/、归档/、scripts/、.codebuddy/、 .workbuddy/memory/;共 398 件,其中 >60 KB 的 26 件全为文档。 排除(.gitignore):tmp/、待清理/、运行态日志与缓存、*.db 与 DB 备份整目录、 打包二进制(*.tar.gz / *.tgz)、记忆修复前备份。
184 lines
13 KiB
Markdown
184 lines
13 KiB
Markdown
# DSH 全球覆盖网络架构复盘(结合全网成熟做法)
|
||
|
||
> 日期: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 用户:「方案只考虑技术实现,跨境数据合规是谁用谁自己考虑」)—— **不再作为方案约束或上抛项** |
|