Neo's Blog

不抽象就无法深入思考
不还原就看不到本来面目!

0%

常见系统设计题系列-即时通信系统

设计要点:

长链接接入网关

  • 接入层:如何做负载均衡(基于IP 还是 基于7层的用户唯一标识)
  • 就近接入
  • 接入层如何升级:尽量减少升级,拆分为负责连接的进程与负责处理业务的进程,两者之间通过共享内存通信

心跳设计

  • 作用:保活
  • 原则:省电 PK 服务器压力

通信协议:采用TCP/HTTP相结合的方式

  • TCP用于低延迟通知类
  • HTTP主要用于拉消息等对延迟不敏感的场景

协议设计

  • 数据安全性
  • 编码复杂度
  • 协议通用型
  • 数据大小

重连策略(客户端与服务端配合)

当一台网关出现问题需要客户端进行重连时,还需要考虑到:不要因为重连问题导致了其他网关服务器也受影响,产生雪崩效应,此时需要考虑以下几点:

  • 打散重连时间:需要进行重连的客户端,在一个时间范围内选择一个随机的时间,这样将这些客户端的重连时间打散,不至于一下子都连接上来。
  • 指数退避:一次重连不上时,客户端还需要再次尝试进行多次重连,然而重连的时间需要像TCP协议那样在阻塞恢复时做指数退避,即第一次重连时间是1秒后,第二次2秒后,第三次4秒后,等等。这个策略也是为了避免由于重连导致的服务雪崩。
  • 服务器保护:上面两条是客户端的重连策略,然而服务器自身也需要进行保护,当服务器判断自己当前的负载到一定程度时,将拒绝客户端的连接请求。

如何保证消息可达(不丢)/唯一(不重复)/保序(不乱序)

  • 不乱序:每条消息都有一条唯一且自增的msg_id
  • 不重复:

消息防丢失

  • 逐条ACK
  • 引入seqno机制:为每一个用户维护一个自增的序列号

存储设计

  • 消息存储库:存储每一个回话下的每一条消息,用于读扩散或者消息漫游;存储周期:长
  • 消息同步库:为每一个用户存储一个使用TIMELINE模型的收件箱,用于读取最新消息(一般是写扩散写入);存储周期:短
  • 万人大群是例外,如果一定要支持的话,可以采用读写扩散混合模式。

后端知识体系不完善,团队成员能力参差不齐
服务或者模块划分混乱,编写的代码不符合DDD风格
营销活动迭代效率急需提升,需要搭建高吞吐量的用户触达平台
架构经验丰富,主导过多种大型系统的设计与开发;以及老系统的平滑重构

你的支持是我坚持的最大动力!