组成
http网关:认证、负载均衡
网络接入层:维持长连接,接收、推送消息
业务服务层:聊天业务相关的消息处理服务
redis消息管道:衔接网络接入层和业务服务层间的内存型消息管道。网络接入层server和业务服务层的service实例1:1,server实例在redis里有一个对应的上行管道,用于server向service推送消息,service处理完后,将加工后的消息加入到目标server的下行管道
redis缓存,内容:
1、组织、群组、连接映射
2、在线用户的最近会话、最新消息数、待ACK列表、收发箱
mongodb:存储最近一月的消息,便于快速获取一月以内的离线消息
mysql:按组织id分库,所有读都从从库读,需要保证主从同步质量
认证
1、user1和user2通过网关认证以及按uid均衡
2、认证成功后,网关返回token,和用户相关的组织信息、群关系、最近会话、最新消息数
3、以客户端上次获取消息的最晚时间戳,如果没有该时间戳,则用上次登录时间戳为准,异步初始化用户的最近一月内的离线消息
连接
1、根据网关的均衡情况,user1和serverA建立连接,user2和serverB建立连接,
2、server对user的token进行校验
3、通过校验的user,server更新连接映射表到redis缓存,否则直接close连接
4、推送离线消息
聊天消息
1、user1向user2发聊天消息,serverA收消息后进行基本的协议、防攻击、去重校验,指定消息序号、然后pub到redis管道
2、业务处理层sub到聊天消息,将消息发布到kafka,更新待user2 的ack列表、最新消息数,同时将添加序号的消息和对user1的ACK pub到redis管道
3、serverA接收到业务处理层pub的ack消息,将ack推送给user1;serverB接收到业务处理层pub的消息,直接推送给user2
4、user2接收到serverB推送的聊天消息后,向serverB 发送ack
5、serverB接收到user2的ack,更新待user2的ack列表
信令消息
1、user1离群,离群操作的信令消息从客户端发往serverA,经过redis消息管道推向业务服务A
2、业务服务A原子更新mysql主库,redis缓存的群组关系,向redis消息管道推送发给user1的ack,向群内所有在线人员推送的更新群成员信令消息,更新待ack消息列表
3、user1接收到ack,所有在线成员接收到更新群成员信令,更新本地群成员并返回ack
4、服务接入层接收到ack,更新待ack列表