首页 › AI System Design › 第12章:设计聊天系统

第12章:设计聊天系统

简介​

A聊天系统支持用户之间的实时消息传递。本章重点探讨如何设计一款包含以下功能的聊天应用:​

•

一对一聊天、群聊(最多100人)、在线状态显示、多设备支持、推送通知​

步骤1:理解问题​

Requirements​

功能:​

◦

一对一与群聊(最多100名成员)、基于文本的消息(最长可达10万字符)。​

◦

在线/离线状态显示、支持多设备、推送通知。​

扩展性:面向5000万日活跃用户设计。​

存储:永久聊天记录。​

步骤2:概要设计​

Communication Protocols​

发送端:使用HTTP协议发送消息,并通过持久连接提高效率。​

​

飞书文档 - 图片

​

接收端:​

◦

轮询:​

▪

客户端定期向服务器查询是否有可用消息。​

▪

由于频繁且冗余的请求而效率低下。​

​

飞书文档 - 图片

​

​

​

Components​

​

​

​

​

无状态服务:​

◦

处理用户注册、登录及个人资料管理。​

◦

与服务发现集成,以推荐最佳聊天服务器。​

有状态服务:​

◦

聊天服务器维持持久的WebSocket连接。​

◦

负责消息的投递与同步。​

第三方集成:​

◦

推送通知服务用于向用户通知新消息。​

◦

有关通知的实现,请参阅“通知系统”章节。​

​

​

Design​

客户端通过持久化的WebSocket连接与聊天服务器保持通信,以实现实时消息传递。​

​

​

•

聊天服务器负责消息的发送与接收。​

•

在线状态服务器管理用户的在线/离线状态。​

•

API服务器处理所有业务,包括用户登录、注册、修改个人资料等。​

•

通知服务器负责推送通知的发送。​

•

最后,键值存储用于保存聊天记录。之所以采用键值存储来存放聊天历史数据,主要有以下几个原因:​

◦

它支持轻松的水平扩展。​

◦

KV存储能够以极低的延迟访问数据。​

◦

关系型数据库难以应对数据的长尾问题。当索引规模增大时,随机访问的开销会显著增加。​

◦

KV存储被其他经过验证的可靠聊天应用所采用。例如,Facebook Messenger和Discord都使用了它。​

以下是单聊和群聊的数据模型。​

•

主键是消息ID,有助于确定消息的顺序。​

•

对于群聊,复合主键为(channel_id, message_id)。​

◦

可以使用像Snowflake这样的全局64位序列号生成器来生成ID。​

◦

更好的做法是使用本地序列号生成器。所谓本地,是指ID仅在单个分组内唯一。​

◦

本地ID之所以有效,是因为只需在一对一聊天或群聊中维护消息的顺序即可。​

​

​

​

​

50%

​

​

​

​

50%

​

​

步骤3:设计深度剖析​

Service Discovery​

​

​

•

服务发现的主要作用是根据地理位置、服务器容量等标准,为客户端推荐最合适的聊天服务器。​

•

用途Apache Zookeeper用于根据地理位置和服务器容量等标准分配聊天服务器。​

•

确保负载均衡高效,并最大限度地降低延迟。​

Messaging Flows​

一对一聊天​

用户A向聊天服务器1发送一条消息。​

聊天服务器1分配一个唯一的消息ID,并将该消息存储在键值存储中。​

如果用户B在线,该消息将被转发至聊天服务器2,并保持持久化的WebSocket连接。​

如果用户B处于离线状态,则发送一条推送通知。​

群聊​

​

​

•

消息会被复制到群组中每位收件人的个人收件箱。​

•

这简化了同步过程,但对大型群组而言成本较高。​

•

在接收端,一个接收者可以收到来自多个用户的消息。每个接收者都拥有一个收件箱(消息同步队列),其中存放着来自不同发件人的消息。​

​

​

​

​

消息同步​

许多用户拥有多个设备。我们需要在各设备之间同步消息。每个设备都维护一个名为 cur_max_message_id 的变量,用于记录该设备上最新的消息 ID。满足以下两个条件的消息被视为新闻消息:​

•

收件人ID等于当前登录用户的ID。​

•

键值存储中的消息ID大于当前最大消息ID​

​

​

Online Presence​

心跳机制:​

​

​

扇出模型:​

​

​

​

​

其他注意事项​

Scalability​

•

水平扩展:随着用户数量增加,动态添加服务器。​

•

负载均衡:将流量均匀分配到各台服务器上。​

•

缓存:降低数据库负载,提升响应速度。​

Error Handling​

•

重试机制:通过重试和队列处理消息投递失败。​

•

服务器故障:在发生故障时,利用服务发现机制分配新服务器。​

Future Extensions​

媒体支持:增加对照片和视频的处理功能,包括压缩与云存储。​

端到端加密:确保消息隐私。​

客户端缓存:减少数据传输,提升性能。​

提升加载速度:采用地理分布式的缓存网络。​