设计要点:
长链接接入网关
- 接入层:如何做负载均衡(基于IP 还是 基于7层的用户唯一标识)
- 就近接入
- 接入层如何升级:尽量减少升级,拆分为负责连接的进程与负责处理业务的进程,两者之间通过共享内存通信
心跳设计
- 作用:保活
- 原则:省电 PK 服务器压力
通信协议:采用TCP/HTTP相结合的方式
- TCP用于低延迟通知类
- HTTP主要用于拉消息等对延迟不敏感的场景
协议设计
- 数据安全性
- 编码复杂度
- 协议通用型
- 数据大小
重连策略(客户端与服务端配合)
当一台网关出现问题需要客户端进行重连时,还需要考虑到:不要因为重连问题导致了其他网关服务器也受影响,产生雪崩效应,此时需要考虑以下几点:
- 打散重连时间:需要进行重连的客户端,在一个时间范围内选择一个随机的时间,这样将这些客户端的重连时间打散,不至于一下子都连接上来。
- 指数退避:一次重连不上时,客户端还需要再次尝试进行多次重连,然而重连的时间需要像TCP协议那样在阻塞恢复时做指数退避,即第一次重连时间是1秒后,第二次2秒后,第三次4秒后,等等。这个策略也是为了避免由于重连导致的服务雪崩。
- 服务器保护:上面两条是客户端的重连策略,然而服务器自身也需要进行保护,当服务器判断自己当前的负载到一定程度时,将拒绝客户端的连接请求。
如何保证消息可达(不丢)/唯一(不重复)/保序(不乱序)
- 不乱序:每条消息都有一条唯一且自增的msg_id
- 不重复:
消息防丢失
- 逐条ACK
- 引入seqno机制:为每一个用户维护一个自增的序列号
存储设计
- 消息存储库:存储每一个回话下的每一条消息,用于读扩散或者消息漫游;存储周期:长
- 消息同步库:为每一个用户存储一个使用TIMELINE模型的收件箱,用于读取最新消息(一般是写扩散写入);存储周期:短
- 万人大群是例外,如果一定要支持的话,可以采用读写扩散混合模式。
后端知识体系不完善,团队成员能力参差不齐
服务或者模块划分混乱,编写的代码不符合DDD风格
营销活动迭代效率急需提升,需要搭建高吞吐量的用户触达平台
架构经验丰富,主导过多种大型系统的设计与开发;以及老系统的平滑重构