架构图
整个系统按层画在一张图上,一条消息的路径用编号标出。首页的简版只有四层和四步;这里是工程版,画到每个部件和每一跳。
一条消息怎样穿过系统:先可靠地收下(步骤 1–4),再异步地送到每台设备(5–7);离线的设备回来时自己拉取(8)。
- 发送:消息从 Ana 的长连接进入网关
- 网关看会话 ID,转给负责这个会话的消息服务
- 先看消息 ID 最近见没见过(重发就原样回上次的序号和 ACK;更晚的重发由存储里的唯一键挡住),再检查能否发言、分配会话内的序号,写入消息日志(持久化的队列)
- 写入成功后,消息服务回 ACK:发送方只等到这一步
- 分发层从日志读取,写入消息存储,再去分发(从这里起是异步的)
- 确定接收方,扩散(写扩散时写入每人的信箱),查在线路由表
- 经 Ben 手机所在的网关推送。没有在线连接的手机改走系统推送,它只是提醒;网页这里不用系统推送,下次打开时补齐
- 离线的设备回来后带着同步游标来拉(游标指向它在自己信箱里读到的位置),同步服务从信箱(写扩散)或群的时间线(读扩散)返回缺的消息;在线的设备发现会话序号断档也会去拉,推送和拉取重叠时按序号去重
蓝色实线:消息的路径蓝色虚线:拉取 灰线:调用、写入、通知虚线框:IM 之外点线:同步与异步的分界
业内常说的“接入层、逻辑层、存储层”:连接层就是接入层,消息层和分发层合起来就是逻辑层。消息日志通常用基础设施里的消息队列实现,比如一个按会话分区的主题。
点任意一层或卡片,看它做什么、难在哪、在哪几章深入讲。