WhatsApp 日处理400亿消息的架构

WhatsApp 是全球最大的即时通讯应用,日处理 400 亿条消息,高峰期每秒 700 万条消息(2015 年数据,用户从 9 亿增长到 20 亿+后规模更大)。支撑这个规模的核心是一台只有约 50 名工程师维护的后端系统——这得益于 Erlang/OTP 的并发模型和精心设计的消息架构。

一、技术选型:为什么用 Erlang

WhatsApp 的创始人 Jan Koum 选择了 Erlang,一个相对小众的函数式编程语言。Erlang 的核心优势:

特性 说明
轻量级进程 每个 Erlang 进程只占 ~300 字节,一台机器可运行数百万进程
Actor 模型 每个连接映射为一个 Erlang 进程,进程间通过消息传递通信
热更新 不停止服务即可更新代码
容错 “Let it crash” 哲学 + Supervisor 树自动重启故障进程
分布式原生 内置跨节点通信,多台机器像一个整体

在 WhatsApp 的架构中,每个用户会话就是一个 Erlang 进程——这意味着 1 亿在线用户 = 1 亿个 Erlang 进程,在几百台服务器上就可以承载。

二、FreeBSD + YAWS

WhatsApp 使用 FreeBSD 作为服务器操作系统,Web 服务器使用 YAWS(Yet Another Web Server),同样是 Erlang 编写的。

选择 FreeBSD 的理由:

  • 更好的网络栈性能(相比 Linux)
  • 更稳定的长时间运行表现
  • 更简单的系统调优

三、消息投递流程

消息的生命周期:

1
发送方 A → WhatsApp 服务器 → 接收方 B

具体流程:

1
2
3
4
5
6
7
8
9
1. A 发送消息 "Hello"B
2. A 的设备通过长连接(MMS/XMPP)发送到 WhatsApp 服务器
3. 服务器在内存中查找 B 的会话(另一个 Erlang 进程)
├─ B 在线 → 直接将消息投递到 B 的连接进程
├─ B 离线 → 消息存入 B 的离线消息队列
└─ B 不存在 → 返回错误
4. 服务器返回 ACK 给 A(单勾 = 已发送)
5. B 收到消息 → 服务器返回第二个 ACK(双勾 = 已送达)
6. B 打开消息(Blue Ticks)→ 服务器返回第三个 ACK(双蓝勾 = 已读)

四、离线消息存储

用户离线时的消息存储在服务端,上线后一次拉取。WhatsApp 早期使用 MySQL,后来根据需求做了优化:

  • 每条消息(包括多媒体)的元数据存储在 MySQL
  • 消息正文和附件在本地 SSD 缓存,定期清理
  • 消息队列按 receiver_id 分片,确保同一用户的所有消息在同一台机器上处理

五、多媒体消息处理

WhatsApp 每天处理数十亿张图片、视频和语音消息。多媒体消息的处理流程:

1
2
3
4
5
1. 发送方上传图片至 WhatsApp 多媒体服务器
2. 服务器压缩/优化图片(降低流量消耗)
3. 发送方收到媒体 ID
4. 将媒体 ID 作为普通消息发送
5. 接收方通过媒体 ID 下载图片

六、端到端加密

WhatsApp 使用 Signal 协议实现端到端加密,保证只有通信双方能读取消息内容——WhatsApp 自己也无法解密。

加密流程简化:

  1. 双方通过 X3DH(Extended Triple Diffie-Hellman)协议交换公钥
  2. 使用 Double Ratchet Algorithm 为每条消息生成新的对称密钥
  3. 即使某条消息的密钥被破解,其他消息仍然安全(前向安全性)

加密在客户端执行,WhatsApp 服务器只负责传输加密后的二进制数据。

七、扩展性

WhatsApp 的关键扩展性设计:

策略 说明
用户级分片 按 user_id 哈希分配到不同服务器,同一用户的请求始终路由到同一台服务器
无共享架构 不同服务器之间不共享数据库连接或状态,每个分片完全独立
数据库分离 用户数据(关系、资料)、消息数据、多媒体数据分别由不同的数据库集群负责
读写分离 消息写入走主库,消息读取可以使用从库

八、容量增长

WhatsApp 从 50 人团队支撑 4.5 亿用户,到 Facebook 收购后扩展到 20 亿+:

  • 4.5 亿用户(2014):约 50 名工程师,~700 台服务器,Erlang/FreeBSD
  • 20 亿+ 用户(2020):整合 Facebook 基础设施(将部分 MySQL 迁移到 Facebook 的 RocksDB 方案),增加多数据中心支持

核心经验:Erlang/OTP 的并发模型使得少量服务器可以承载海量连接——每个连接 ~300 字节,1 亿连接只需 ~30GB 内存(加上消息缓冲约 100GB)。这在其他语言(如 Java 的线程模型)下是不可能的——1 亿个 Java Thread(每个 ~1MB 栈)需要 100TB 内存。

九、小结

WhatsApp 的架构是”极简主义”的典范——用 Erlang/OTP 的轻量级进程模型,每个用户会话一个进程,配合 FreeBSD + YAWS,用极小的团队和服务器资源支撑了全球最大的消息系统。其设计哲学:用正确的抽象(Actor 模型)应对并发,用无共享架构保证可扩展性,用端到端加密保证隐私。