拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

规模化联邦方案(去火管化:每群/频道独立主题 + DHT/见证发现 + 真 nm-federation + NAT 直投 + E2E 配对)

规模化联邦方案(去火管化:每群/频道独立主题 + DHT/见证发现 + 真 nm-federation + NAT 直投 + E2E 配对)

规模化联邦方案(去火管化:每群/频道独立主题 + DHT/见证发现 + 真 nm-federation + NAT 直投 + E2E 配对)

现有联邦靠一条 gossip 主题全量广播所有群/频道/私聊/命名,nm-federation仍是 16 行桩。
目标:按主题订阅——流量与可见性收敛到相关方,可扩展、无单点、为 E2E 预留。
这是一条纯后端 crate 线(crates/nm-federation/nm-gossip/nm-node),惠及桌面+移动,不碰clients/app与clients/mobile,可与移动端并行。
基线见CURRENT_STATE_ANALYSIS.md。本文为方案稿(评审后动手)。

0. 背景与「火管」三宗罪

当前跨节点收敛(群/频道/私聊/命名)统一走一个联邦级 gossip 主题nmspace-groups:<fed>,承载GroupGossip{ Group announce | Gram msg | Gram direct | NameRecord },全量广播给联邦内每个节点,各记录按origin去自环、LWW/墓碑合并。它当初是为绕开「跨 NAT s2s 直拨超时」而快速打通的权宜之计,但:

  1. 隐私:非成员节点也收到所有群/频道/私聊的元数据与明文(E2E 未接)。
  2. 规模:带宽/存储 ∝O(节点数 × 全量消息)——联邦越大越不可持续。
  3. 架构债:nm-federation是桩,真正的收敛逻辑散在nm-node的 gossip hack 里,难演进。

1. 设计目标与原则

  • 最小可见性:一条消息只到达它该到的成员/订阅者。
  • 可扩展:单节点开销随其实际所在的群/频道数,而非联邦规模。
  • 无单点、可自托管:发现可去中心(DHT),弱锚(见证节点)仅做 bootstrap。
  • 兼容既有:复用 dial-by-key、GroupGossip信封、LWW/墓碑、content_hash去重。
  • 平滑迁移:灰度双写、版本协商,不停机切换。
  • 为 E2E 预留:主题边界 ↔ 加密群边界(MLS)天然对齐。

2. 架构总览

3. 主题模型(Topic Model)

对象主题谁 join收敛
群nmspace-group:<gid>群成员消息=gossip;成员/元信息=iroh-docs
频道nmspace-channel:<cid>订阅者同上(频道现为内存态,顺带持久化)
命名nmspace-names:<domain>关心该域的节点NameRecord LWW/墓碑(见 §7)
私聊不上广播主题——直投 / 收件箱主题(见 §6)
  • GroupGossip信封基本复用,但按 topic 隔离;origin去自环、content_hash去重照旧。
  • 一个节点可同时在很多主题里;由nm-federation统一管理其订阅集与生命周期。

4. 发现与引导(Discovery & Bootstrap)

  • 症结:iroh-gossipjoin 一个主题需要已知 bootstrap peer;而非成员根本不在主题里,无从得知第一个 peer。
  • 方案 A(DHT / pkarr):把群公钥 → {topic, 种子 peer 列表, 成员根哈希}发布到 iroh/pkarr 的 DHT,键=群公钥;新成员查询即得 bootstrap。去中心、无锚。
  • 方案 B(见证/锚定节点 witness/anchor):每群指定少量锚定节点(创建者 home + 若干,可轮换),常驻该主题、对外 dial-by-key 可达,充当稳定 bootstrap + 成员目录。弱锚、可多副本。
  • 推荐 A+B 混合:锚定节点给稳定冷启动,DHT 做无锚兜底;群公钥不可枚举,避免群被遍历发现。

5. nm-federation 真实化(从桩到模块)

把散落在nm-node的 gossip 收敛逻辑收敛进crates/nm-federation,职责分层:

  • 传输/实时:iroh-gossip每主题一个GossipTopic——低延迟消息广播。
  • 状态/收敛:iroh-docs每群一个复制文档(成员集、角色、群资料、墓碑),只在成员间同步——强收敛、可回放。
  • 订阅生命周期:join/leave/rejoin、announce 心跳、peer 采样与重连、主题 GC。

API 草图:

pubtraitFederation{asyncfnjoin_group(&self,gid:GroupId)->Result<GroupHandle>;asyncfnleave_group(&self,gid:GroupId)->Result<()>;asyncfnpublish(&self,gid:GroupId,env:GroupGossip)->Result<()>;fnsubscribe(&self,gid:GroupId)->implStream<Item=GroupGossip>;asyncfnmembers(&self,gid:GroupId)->Result<MemberSet>;// 来自 iroh-docs}

注意版本对齐:iroh 1.2与iroh-gossip/iroh-docs 0.10x的兼容是前置工作(分析里已标记)。

6. 私聊与 NAT 直投症结

  • 根因:私聊被塞进火管,是因为跨 NAT 的 s2s 直拨当初超时(fed sync failed: s2s request timed out)。去火管的前提是恢复 NAT 健壮的直投。
  • 路径2(首选):修好 irohrelay + holepunch + 连接复用;收件人在线→直投,离线→入其home node 的 redb inbox补投(home 经 relay 稳定可达)。第一要务是定位当初超时真因:relay url 未配 / ALPN 不符 / 每次新建连接未复用 / dial 目标是节点而非其 home。
  • 路径3(兜底):nmspace-inbox:<recipient_pub>每收件人一主题,仅收件人与其 home join;发件方 publish。避免全广播又不依赖直拨;元数据仅对 join 者可见,配 E2E 缓解。

7. 命名去火管化

  • 现:NameRecord走火管。目标:按域主题nmspace-names:<domain>,只有关心该域的节点 join;或并入 DHT(domain→node本就经 nm-domain/pkarr 发现)。
  • LWW + 墓碑(空client_pubkey+ 更高 serial)语义不变;home_node自签名不变。

8. E2E(MLS)配对

  • 每群一主题 ↔ 每群一个 MLS 群:预留的 openmls 终于可接。主题传输密文 + MLS 握手(Welcome/Commit);成员增减 ↔ MLS add/remove(与 §5 的成员文档联动)。
  • 私聊用 1:1 MLS 或 X25519 封装。去火管 + E2E 一起,才真正消除「明文广播全联邦」。

9. 迁移与兼容(灰度,不停机)

  1. 双写:节点同时在火管 + 新 per-topic 发;收端按content_hash去重。
  2. 协商:announce带supports_per_topicfeature flag,混合网络平滑过渡。
  3. 切流:成员/订阅迁到新主题后,发端停火管、仅新主题。
  4. 退役:联邦主题仅作「发现兜底 / 老节点兼容」保留一段时间后移除。

10. 分阶段路线(每阶段可跨网验证)

  • F0 · nm-federation 骨架:topic 注册表 + 订阅 API + 单测;内部仍走火管,线上行为不变。
  • F1 · 群/频道切 per-topic:成员 join 自己群主题;双写 + 去重;锚定节点 bootstrap。
  • F2 · DHT/pkarr 发现:无锚也能 join;群公钥不可枚举。
  • F3 · 私聊去火管:定位并修 NAT 直投;inbox 主题兜底。
  • F4 · 命名去火管:按域主题 / DHT。
  • F5 · E2E + 退役火管:每群 MLS 接入;联邦火管下线。
  • 里程碑沿用现有多 seed + 集成测试 + 跨网真机(见 memoryseed-deploy-pipeline/federation-delivery-mechanisms)。

11. 风险与开放问题

  1. 多主题开销:节点在大量群时,N 个 gossip 主题的连接/采样/内存——需 peer 采样上限与懒 join。
  2. iroh-docs × iroh 1.2 版本对齐(前置)。
  3. NAT 直投真因未定位:F3 前必须用真机 + relay 实测复现。
  4. 见证节点信任/激励:谁当锚、下线与轮换、防女巫。
  5. DHT 隐私/可用性:发现延迟、群枚举(靠不可枚举群公钥缓解)。
  6. 墓碑/LWW GC:per-topic 下的垃圾回收与存储增长。
  7. 开放问题:
    • 频道是否也要成员鉴权(公开频道 vs 私有频道的主题可见性)?
    • 私聊兜底选「直投为主」还是「inbox 主题为主」,取决于 relay 实测结论。
    • E2E 先上私聊还是先上群?(群的成员变更+MLS 更复杂)
    • 是否顺带把频道做持久化(现为内存态,重启丢)。
返回列表