第一步 理解问题,确定设计范围
市场主流的聊天应用的侧重有:一对一聊天,群聊,大群互动,低延迟语音聊天(如Discord) 本例设计需求:
- 同时支持一对一与群聊,传输低延迟
 - 同时支持移动端和web,可同时登录多设备
 - 50 millions DAU
 - 群聊最多100人
 - 核心功能:一对一,群聊,在线状态,推送通知。简单起见,仅支持文字聊天即可
 - 单条消息100k大小限制
 - 聊天记录永久保存
 - 可暂时不考虑端到端加密
 
第二步 high-level设计
聊天服务使用的网络协议:
- 轮询
 - 长轮询
 - webSocket
 
High-level设计,分为三个部分,分别为:
- 无状态服务(API,用于管理登录注册,用户配置文件等)
 - 有状态服务(聊天服务)
- 聊天服务器
 - 在线状态服务器
 
 - 第三方集成(通知推送)
 
存储:采用NoSQL键值存储
一对一聊天:主键为message_id
群聊:复合主键(channel_id,message_id)
message_id的生成方法参考第七章
第三步 深入讨论
服务发现:根据地理位置、服务器容量等标准为客户端推荐最佳的聊天服务器。(Apache Zookeeper是一种流行的服务发现开源解决方案)
消息流:
一对一聊天流程
- 用户A向聊天服务器1发送聊天消息。
 - 聊天服务器1从ID生成器获取消息ID。
 - 聊天服务器1将消息发送到消息同步队列。
 - 消息存储在键值存储中。
 - 如果用户B在线,则消息将转发到用户B连接的聊天服务器2。如果用户B离线,则从推送通知服务器发送推送通知。
 - 聊天服务器2将消息转发给用户B。用户B和聊天服务器2之间存在持久的WebSocket连接。
 
多设备消息同步:每个设备都维护一个cur_max_message_id变量。登录时从存储中获取id>cur_max_message_id进行同步
群聊:当群聊人数较小时,可将用户A的消息复制到每个组成员的消息同步队列
在线状态:用户登录,登出,断线会触发状态变更。为防止在线状态频繁变更,可引入心跳机制。
第四步 总结
其它可讨论的点:
- 支持照片和视频等媒体文件
 - 端到端加密
 - 客户端缓存
 - 地理分布式网络来缓存用户的数据、频道,缩短加载时间
 - 错误处理
 - 聊天服务器错误
 - 消息重发机制
 
](https://zhangwenshan001.github.io/images/systemdesign.png)