设计 WhatsApp/微信:实时通讯系统架构

FreeGuideOnline 最新 2026-06-18

设计 WhatsApp/微信:实时通讯系统架构

本教程带你从零开始理解大型实时聊天系统(如 WhatsApp、微信)的底层架构设计。你将掌握核心组件、消息路由、状态同步与高可用策略,无需庞大背景知识。


1. 系统核心需求与挑战

在设计架构前,先明确业务要求和隐藏的技术难点。

功能需求一览

  • 一对一聊天:实时发送文本、图片、视频、文件。
  • 群组聊天:支持千人级别群组。
  • 在线状态展示:在线、离线、最后上线时间。
  • 消息已读回执:单勾、双勾、蓝色双勾。
  • 消息历史记录:永久保存,多设备同步。
  • 推送通知:即使 App 在后台也能收到。

非功能性需求(来自亿级用户的考验)

  • 低延迟:消息端到端延迟 < 200ms。
  • 高可靠:消息不丢失、不重复(精确一次)。
  • 高并发:同时支撑数亿长连接。
  • 安全性:端到端加密(E2EE)。
  • 水平扩展:随用户量平滑扩容。

2. 架构全景图

大型聊天系统并非简单的客户端-服务器直连,而是一个分层的分布式系统。

用户A客户端 ──> 长连接网关 ──> 消息队列 ──> 消息处理服务 ──> 消息存储
                                          └──> 状态服务 / 群组服务
用户B客户端 <── 长连接网关 <──────────────┘

这个逻辑分层包含以下核心角色:

  • 接入网关:管理海量客户端的 WebSocket/TCP 长连接。
  • 消息路由:决定消息如何送达目标用户。
  • 业务服务:处理群组、好友关系、在线状态。
  • 持久化层:消息存储、时序、索引。
  • 多媒体处理:图片压缩、视频转码。
  • 推送通道:离线时通过 APNs/FCM 强提醒。

3. 连接层:长连接网关设计

传统 HTTP 短轮询无法满足即时性,聊天系统采用 持久连接

3.1 技术选型:WebSocket vs 自研 TCP

  • WebSocket:浏览器级兼容,适用于 Web 与简化开发。微信网页版曾使用。
  • 自研私有 TCP:更节省流量(二进制协议),心跳自定义,用于移动 App。WhatsApp 使用 MQTT 改进版或 XMPP+定制。

3.2 网关集群架构

几十亿设备不可能全连一台服务器,采用 连接路由 + 网关集群

  • 客户端通过 DNS 或负载均衡选择合适的边缘节点(就近接入)。
  • 网关节点维护 用户ID → 连接实例 映射(存在于一致性哈希分片中)。
  • 网关本身无状态,状态存储在 Redis 或专用状态服务中,重启不影响连接(连接转移或重连机制)。

3.3 心跳与离线检测

  • 客户端定时发送心跳包(如每 30 秒)。
  • 若 3 个心跳周期无响应,网关将用户标为离线,并通知状态服务。
  • 离线后消息转为推送通知,未捎带的消息缓存在服务端,上线后拉取。

4. 消息核心流程:从发出到送达

以一对一消息为例,详细拆解时序:

4.1 发送路径

  1. 客户端A 通过长连接发送消息({to: B, content: "hello", msgId: M1})。
  2. 网关收到后,先返回发送确认(减少客户端重试),然后将消息投递到内部消息队列(Kafka)
  3. 消息处理服务消费队列:
    • 入库存储(消息持久化)。
    • 解析接收方 B。
    • 从状态服务查询 B 的在线网关节点。
  4. 如果 B 在线,消息直接通过网关间内部通道推送给 B 所在网关;网关再下行给客户端,携带服务端生成的全局序列号 seqID
  5. 如果 B 离线,消息存入待收队列;B 上线后通过 sync 协议 拉取。

4.2 已读回执多级设计

  • 服务器已收到:发送方看到“单勾”。
  • 已送达目标设备:目标网关成功下发,确认回执,发送方看到“双勾”。
  • 对方已读:用户 B 打开对话时,客户端上报 read 事件拉到最大 seqID,服务端更新会话已读游标,并通知 A。

4.3 消息ID与去重

  • 客户端生成全局唯一 msgId(UUID 或时间戳+设备ID+递增数)。
  • 服务端分配单调递增的 seqID,用于历史拉取有序。
  • 通过消息ID去重表防止重复发送(针对网络重试)。

5. 群组消息分发:Fan-out 模型

群组消息是性能瓶颈,对于 5000 人群,不能逐用户写扩散。

5.1 写扩散 vs 读扩散

  • 写扩散:发到群时,将消息复制到每个成员的“收件箱”。此方式查询简单,但大群写入爆炸。
  • 读扩散:消息只存一份到群消息表,成员阅读时实时拉取。查询压力大,但写入恒定。

实用方案:混合模式(大小群区分)

  • 小型群(<100 人):使用写扩散,每个成员拥有独立时间线,拉取快;
  • 大型群(>100 人):读扩散,消息只写一份,成员查看时动态拉取,并缓存热点群消息。

5.2 超大群优化

  • 限制群成员数上限(如微信 500 人,可付费扩增)。
  • 在线用户实时推送;离线用户不推送所有消息,仅记录未读计数,上线后增量拉取。
  • 群消息降级:非活跃成员降低实时推送优先级。

6. 消息同步与多设备方案

用户可能同时登录手机、PC、Web,要求消息在多端实时同步。

6.1 全局消息序列号

每个用户维护一条同步时间线,所有设备共享相同的递增 seqID(用户级)。

  • 服务端为每用户分配一个原子递增序列。
  • 会话内的消息记录通过 (user_id, seq_id) 索引。
  • 新设备登录,上报本地最大 seq,服务端返回增量数据。

6.2 会话列表与状态同步

  • 会话信息(最后一条消息、未读计数等)通过轻量级同步协议更新,减少全量推送。
  • 多设备读回执:设备 A 读某消息后,向服务端上报已读 seq,服务端将游标同步给设备 B,B 自动消除未读。

7. 存储设计:消息、会话与关系链

7.1 消息存储结构

  • 用户消息表(按用户分片):user_id + seq_id 做主键,存储内容、发送方、时间、状态。
  • 群组消息表(按群分片):group_id + tg_seq_id 主键。
  • 消息内容支持 JSON 扩展,不同类型消息(文本、图像、视频)用 content_type 区分,媒体文件存独立对象存储(如 S3/CDN),消息体中只保留文件 URL。

7.2 冷热数据分离

  • 近 30 天热消息存高性能 SSD 数据库(如 MySQL 或 HBase);
  • 历史消息归档至低成本的分布式存储(Cassandra、HDFS),用户检索时查询归档层。

7.3 索引与查询

  • 根据 to_user_id 拉取会话消息,需要联合索引 (to_user_id, seq_id)
  • 图片/文件搜索依靠媒体服务元数据库,与消息内容解耦。

8. 在线状态系统设计

用户“在线/离线/最后上线”需要近实时传播。

8.1 状态传播模型

  • 状态变更由 状态服务 管理,连接层上报。
  • 采用发布订阅模式:A 好友上线,订阅了 A 的状态的好友都会收到变更通知。
  • 为节省广播带宽,推送间隔做限流(例如每 60 秒只推送一次上线/下线批量更新)。

8.2 最终一致性

  • 实时穿透可能延迟,采用弱一致性,用户列表显示的状态可以有几秒滞后。
  • “正在输入”状态通过聊天信道临时高频推送,不属于持久状态。

9. 多媒体消息与附件处理

图片、视频等大文件不能通过长连接信道传输。

9.1 发送流程

  1. 客户端上传文件到媒体服务器,获得临时 ID。
  2. 媒体服务器对图片进行压缩、生成缩略图;视频进行转码(不同分辨率)。
  3. 上传完成后返回最终 CDN URL 和文件信息哈希。
  4. 客户端将元信息(尺寸、格式、URL)打包进聊天消息发送。

9.2 接收端展示

  • 接收方收到消息后,根据 URL 从 CDN 加载缩略图直接显示,高清原图按需下载。
  • 端到端加密时,文件需在客户端加密后上传,服务端保存加密后的文件,接收方下载后解密。

10. 高可用与扩展性设计

10.1 服务质量保证

  • 避免单点故障:每个服务多活部署,连接网关宕机,客户端自动重连转移到其他节点。
  • 消息可靠性:消息队列持久化 + 至少一次语义,业务层做幂等处理。
  • 异地多活:核心服务分布在多个数据中心,用户就近接入,数据通过专线同步。

10.2 水平扩展关键点

  • 网关层:依据用户 ID 一致性哈希分片,新增加节点自动重新平衡连接。
  • 消息处理:Kafka 分区按 to_user_id 划分,保证同一用户消息顺序处理。
  • 存储层:用户分库分表,使用用户 ID 后几位取模;群组消息按群分表。
  • 缓存:热点用户会话列表、群信息缓存在 Redis 集群,拦截极大量读请求。

11. 安全与加密(端到端加密概览)

对于注重隐私的聊天系统,需实现 E2EE:

  • 密钥协商:基于 Signal 协议(双棘轮),通过 X3DH 和定期更新会话密钥。
  • 服务端透明:消息在发送端加密,服务端只负责存储密文和路由,无法解密。
  • 群聊加密:采用“发件人密钥”模型(Sender Key)降低加密开销。
  • 身份验证:带外比对安全码(Safety Number)防止中间人攻击。

注:E2EE 实现复杂,但对架构影响主要在消息处理流程中,消息内容无法被服务端解析,搜索功能需在客户端索引或使用同态加密等高级技术(目前很少实现)。


12. 总结:架构演进路线

首先实现 MVP:

  1. 单机 WebSocket 服务器
  2. 内存用户连接映射
  3. 单库存储消息

逐步演进为分布式: 4. 增加网关集群,连接分片 5. 引入消息队列解耦收发 6. 用户消息表分库分表 7. 群组写扩散→混合扩散 8. 多媒体独立通道 9. 异地多活与 E2EE 集成

掌握这些原则,你就能按照实际规模裁剪系统,设计出可靠且可扩展的聊天平台。


本教程由「免费在线教程」提供,期待你动手实践架构绘图与模拟实现。