第一步 理解问题,确定设计范围

市场主流的聊天应用的侧重有:一对一聊天,群聊,大群互动,低延迟语音聊天(如Discord) 本例设计需求:

  • 同时支持一对一与群聊,传输低延迟
  • 同时支持移动端和web,可同时登录多设备
  • 50 millions DAU
  • 群聊最多100人
  • 核心功能:一对一,群聊,在线状态,推送通知。简单起见,仅支持文字聊天即可
  • 单条消息100k大小限制
  • 聊天记录永久保存
  • 可暂时不考虑端到端加密

第二步 high-level设计

  • 聊天服务使用的网络协议:

    • 轮询
    • 长轮询
    • webSocket
  • High-level设计,分为三个部分,分别为:

    • 无状态服务(API,用于管理登录注册,用户配置文件等)
    • 有状态服务(聊天服务)
      • 聊天服务器
      • 在线状态服务器
    • 第三方集成(通知推送)
  • 存储:采用NoSQL键值存储

    • 一对一聊天:主键为message_id

    • 群聊:复合主键(channel_id,message_id)

      message_id的生成方法参考第七章

第三步 深入讨论

  • 服务发现:根据地理位置、服务器容量等标准为客户端推荐最佳的聊天服务器。(Apache Zookeeper是一种流行的服务发现开源解决方案)

  • 消息流:

    • 一对一聊天流程

      1. 用户A向聊天服务器1发送聊天消息。
      2. 聊天服务器1从ID生成器获取消息ID。
      3. 聊天服务器1将消息发送到消息同步队列。
      4. 消息存储在键值存储中。
      5. 如果用户B在线,则消息将转发到用户B连接的聊天服务器2。如果用户B离线,则从推送通知服务器发送推送通知。
      6. 聊天服务器2将消息转发给用户B。用户B和聊天服务器2之间存在持久的WebSocket连接。
    • 多设备消息同步:每个设备都维护一个cur_max_message_id变量。登录时从存储中获取id>cur_max_message_id进行同步

    • 群聊:当群聊人数较小时,可将用户A的消息复制到每个组成员的消息同步队列

  • 在线状态:用户登录,登出,断线会触发状态变更。为防止在线状态频繁变更,可引入心跳机制。

第四步 总结

其它可讨论的点:

  • 支持照片和视频等媒体文件
  • 端到端加密
  • 客户端缓存
  • 地理分布式网络来缓存用户的数据、频道,缩短加载时间
  • 错误处理
  • 聊天服务器错误
  • 消息重发机制