1606 字
约 5 分钟
7
S02-A01 · 实时通信架构选型
适用读者:要为"百万级推送/实时消息"做架构决策并对成本负责的人。
前置:S02-J03(容量估算)、S02-B07(四方案)。
版本基线:WebSocket(RFC 6455)、SSE、Redis 7 Pub/Sub 或 Kafka 3.x(示例)。
覆盖旧文:—(E 驱动)
覆盖扩展:E-S02-025(扇出与消息队列)、E-S02-026(网关治理)。
上一篇:S02-J03 · 实时通信工程:连接数、心跳、消息可靠性与水平扩展
下一篇:S02-A02 · API 与 RPC 治理。
1. 业务目标与约束先摆清楚
| 目标 | 指标 | 说明 |
|---|---|---|
| 延迟 | P99 < 200 ms(消息产生 → 送达) | 聊天/协作类 |
| 规模 | 峰值 100 万在线连接 | 决定机器数 |
| 可靠 | 不丢、不重、可补发 | 断线期间消息要能补 |
| 成本 | 每千连接每月成本可算 | 决定自建 vs 托管 |
| 约束 | 影响 |
|---|---|
| 客户端类型(浏览器/App/IoT) | 决定能否用 WebSocket、是否需要长连接驻留 |
| 是否有强合规要求(数据不出内网) | 排除公有推送服务 |
| 团队运维能力 | 自建需要 7×24 值班 |
| 现有基础设施(K8s、MQ、Redis) | 决定复用成本 |
2. 三个可行方案
| 方案 | 架构 | 优点 | 缺点 |
|---|---|---|---|
| A. 自建长连接 | LB → WS 节点(无状态)→ MQ → 业务 | 完全可控、延迟最低、成本随规模线性 | 运维重、要自己做容量与故障处理 |
| B. 推送服务(厂商/云) | 业务 → 厂商 API → 厂商通道 → 客户端 | 上线快、免运维、跨平台(APNs/FCM/厂商通道) | 按量计费、数据出境、延迟不可控、厂商故障即你的故障 |
| C. MQ + 客户端拉取 | 业务 → MQ → 客户端轮询/SSE 拉 | 实现最简单、极易水平扩展 | 实时性差(秒级)、无效请求多 |
2.1 选型判据
延迟要求 < 500 ms 且规模 > 10 万?
├── 是 → A(自建)
└── 否 → 客户端是移动 App 且只需"通知"?
├── 是 → B(推送服务)
└── 否 → C(MQ + 拉取)
实践中的常见组合:
- A + B:在线走 WebSocket,离线走厂商推送(覆盖"用户不在线"的场景)。
- A + C:核心消息走长连接,非实时通知走拉取(降成本)。
3. 容量估算(可交付的算式)
以 A 方案、100 万并发连接为例:
| 项 | 算式 | 结果 |
|---|---|---|
| 单机连接数 | 保守取 5 万/节点(留 50% 余量) | 需 20 节点 |
| 单机内存 | 5 万 × 8 KB ≈ 400 MB + 业务缓冲 | 1 GB/节点起 |
| 心跳 QPS | 100 万 / 30 s | 3.3 万 QPS |
| 消息广播 | 1 万条/秒 × 100 万订阅 = 10⁹ 次写 | 不可行 → 必须分片 |
| 带宽 | 每条消息 200 B × 20 万条/秒 | 40 MB/s ≈ 320 Mbps |
降本关键:
| 手段 | 收益 |
|---|---|
| 心跳间隔从 10 s 调到 30 s | 心跳 QPS 降 2/3 |
| 消息合并(100 ms 批量) | 写次数下降一个量级 |
| 按 topic 分片订阅 | 广播退化为组播 |
| 冷连接降级(空闲 > 5 min 转 SSE/短轮询) | 释放连接名额 |
4. 故障域与降级
| 故障 | 影响 | 降级策略 |
|---|---|---|
| 单个 WS 节点挂 | 该节点上 5 万用户断连 | 客户端抖动重连到其他节点(B08 §4) |
| MQ 不可用 | 消息积压、延迟上升 | 限流 + 本地缓冲 + 告知用户 |
| 推送厂商故障(B 方案) | 离线通知全丢 | 多厂商冗余 / 降级为 App 内拉取 |
| LB 会话表异常 | 大面积重连 | 提前压测、连接数上限 |
| 证书过期 | 全线握手失败 | 到期监控(S01-A02) |
可观测性三件套:连接数、心跳超时率、消息端到端延迟(P50/P99)。
5. 迁移与回滚
| 阶段 | 动作 | 回滚 |
|---|---|---|
| 双跑 | 新旧通道并行,按用户 ID 灰度切 5% → 50% → 100% | 切回旧通道(开关) |
| 数据 | 会话与离线消息存外部存储(Redis/DB) | 双写期保证可回退 |
| 客户端 | 版本兼容(旧客户端继续用轮询) | 服务端保留旧接口 3 个月 |
| 验收 | 灰度组 P99、错误率、连接成功率对比 | 任一指标劣化 > 20% 即回滚 |
铁律:开关放配置中心,不放客户端——回滚速度决定故障时长。
6. 交付物(评审用)
| 交付物 | 内容 |
|---|---|
| 拓扑图 | LB / 连接层 / MQ / 业务 / 存储 五段 |
| 容量表 | §3 的算式与假设(含峰值倍数) |
| 成本表 | 节点数 × 单价 + 带宽 + 托管费 |
| 故障演练计划 | 节点 kill、MQ 断连、证书过期 |
| ADR | 方案选择与被否方案原因(S01-A04 模板) |
7. 自检(架构师版)
- 100 万连接,为什么"一个节点扛 10 万"通常不是好选择?
- 广播 1 万条/秒给 100 万订阅者,哪一步最先崩?怎么改?
- 选 B(推送服务)时,最大的隐性成本是什么?
- 灰度切换时,你用什么指标判定"必须回滚"?
- 你的容量表里,哪些数字是假设而不是实测?如何验证?
8. 下一篇
S02-A02 · API 与 RPC 治理:网关、契约、版本与灰度
推送架构解决"服务端怎么找到客户端",最后一篇解决"服务之间怎么长期不炸":契约单一来源、破坏性变更的处置、网关职责边界与灰度回滚。这一篇同时是 S02 的方法论收尾。
本篇属于系列《S02 · 计算机与网络基础》,架构师层第 1 篇。扩展点 E-S02-025/026。
S02-A01 · 实时通信架构选型
https://www.clxhxhhr.top/posts/5195/ 评论
0 条
还没有评论,先写一条吧。