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. 自检(架构师版)

  1. 100 万连接,为什么"一个节点扛 10 万"通常不是好选择?
  2. 广播 1 万条/秒给 100 万订阅者,哪一步最先崩?怎么改?
  3. 选 B(推送服务)时,最大的隐性成本是什么?
  4. 灰度切换时,你用什么指标判定"必须回滚"?
  5. 你的容量表里,哪些数字是假设而不是实测?如何验证?

8. 下一篇

S02-A02 · API 与 RPC 治理:网关、契约、版本与灰度

推送架构解决"服务端怎么找到客户端",最后一篇解决"服务之间怎么长期不炸":契约单一来源、破坏性变更的处置、网关职责边界与灰度回滚。这一篇同时是 S02 的方法论收尾。


本篇属于系列《S02 · 计算机与网络基础》,架构师层第 1 篇。扩展点 E-S02-025/026。

S02-A01 · 实时通信架构选型
https://www.clxhxhhr.top/posts/5195/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。