教你IM即时消息系统的架构设计
1 ⽤户视图的IM
IM系统组成
⽤户账号
聊天的参与需要⽤户,所以需要有⼀个⽤户账号,⽤来给⽤户提供唯⼀标识,以及头像、昵称等可供设置的选项
乃万成立个人工作室账号关系
账号之间通过某些⽅式(⽐如加好友、互关等)构成账号间关系⽹
联系⼈列表
你的好友列表或聊天对象的列表。其中你可选择⼀个联系⼈进⾏聊天互动等操作
消息
在聊天互动这个环节产⽣了消息
聊天会话
你和对⽅的聊天消息记录就组成了⼀个聊天会话,在会话⾥能看到你们之间所有的互动消息
2 研发视图的IM
2.1 组成
客户端
⽤户收发消息的终端,内置的客户端程序和服务端进⾏⽹络通信,⽤来承载⽤户的互动请求和消息接收功能。
接⼊服务
为客户端提供消息收发的出⼊⼝,即⽹关层服务。
接⼊层避免业务可使⽤统⼀协议的header,body部分直接透传⼆进制,或把body的编码分委托给其他的编解码api。另外对于protobuf还不够紧凑的问题可以再gzip⼀下后再下推客户端。
发送的消息先由客户端通过⽹络给到接⼊服务,然后再由接⼊服务递交到业务层进⾏处理
接⼊服务的功能:
七夕情人节句子
保持连接
消息推送
当服务端有消息需要推送给客户端时,也是将经过业务层处理的消息先递交给接⼊层,再由接⼊层通过⽹络发送到客户端。
协议的编解码
编解码实际主要是为了节省⽹络流量,系统会针对传输的内容进⾏紧凑的编码(⽐如Protobuf),为了让业务处理时不需要关⼼这些业务⽆关的编解码⼯作,⼀般由接⼊层来处理。
session维护
session的作⽤是标识“哪个⽤户在哪个TCP连接”,⽤于后续的消息推送能够知道,如何到接收⼈对应的连接来发送。
接⼊服务还负责最终消息的推送执⾏,即通过⽹络连接把最终的消息从服务器传输送达到⽤户设备。
业务处理服务
消息业务逻辑处理,⽐如消息的存储、未读数变更、更新最近联系⼈等。
存储服务
账号信息、联系⼈关系链,以及消息本⾝,都需服务端存储持久化存储。还有⼀些⽤户消息相关的设置,⽐如:⽤户可以设置不接收某些⼈的消息,还有附件。
服务端可以只是维护⼀个⽤于暂存消息和信令的离线buffer,⾄于存多久和产品需求以及监管需求相关。
即时消息可以放到MQ中,或者缓存中,使⽤数据抽取⼯具周期性的将数据提交服务器,进⾏持久化。服务器存储历史数据和近实时的数据。其实就是通过 MQ来异步化解耦消息存储逻辑。
作⽤
会话⼀⽅⽤户不在线,上线时进⾏消息推送
内容审查,监管,电⼦证据,法律要求
数据分析,舆情分析
外部接⼝服务
由于⼿机限制及资源优化的考虑,⼤部分App在进程关闭或长时间后台运⾏时,App和IM服务端的连接会被⼿机os断开。这样当有新的消息产⽣时,就没法通过IM服务再触达⽤户,因⽽会影响⽤户体验。
为让⽤户在App未打开或在后台运⾏时,也能接收到新消息,我们将消息给到第三⽅外部接⼝服务,来通过⼿机操作系统⾃⾝的公共连接服务来进⾏操作系统级的“消息推送”,通过这种⽅式下发的消息⼀般会在⼿机的“通知栏”对⽤户进⾏提醒和展⽰。常⽤的第三⽅系统推送服务:
苹果⼿机⾃带的APNs(Apple Push Notification service)服务
安卓⼿机内置的⾕歌公司的GCM(Google Cloud Messaging)服务
但GCM服务在国内⽆法使⽤,为此很多国内⼿机⼚商在各⾃⼿机系统中,也提供类似的公共系统推送服务,如⼩⽶、华为、OPPO、vivo 等⼿机⼚商都有相应的SDK。
接⼊服务和业务处理服务独⽴拆分原因:
接⼊服务作为消息收发的出⼊⼝,必须⾼可⽤
如果连接服务总不稳定:连不上或频繁断连,⼤⼤影响聊天流畅。
业务处理服务由于随产品需求迭代,变更⾮常频繁,随时有新业务需上线重启。
若消息收发接⼊和业务逻辑处理都在⼀起,势必让接⼊模块随业务逻辑的变更上线⽽频繁起停,导致已通过⽹络接⼊的客户端连接经常性地断连、重置、重连。
这种连接层的不稳定性会导致消息下推不及时、消息发送流畅性差,甚⾄会导致消息发送失败,从⽽降低⽤户消息收发的体验。
所以将“只负责⽹络通道维持,不参与业务逻辑,不需要频繁变更的接⼊层”抽离出来,不管业务逻辑如何调整变化,都不需要接⼊层进⾏变更,这样能保证连接层的稳定性,从⽽整体上提升消息收发的⽤户体验。
业务开发⼈员的⾓度看,接⼊服务和业务处理服务进⾏拆分有助于提升业务开发效率,降低业务开发门槛。
模块拆分后,接⼊服务负责处理⼀切⽹络通信相关的部分,⽐如⽹络的稳定性、通信协议的编解码等。
这样负责业务开发的同事就可以更加专注于业务逻辑的处理,⽽不⽤关⼼让⼈头痛的⽹络问题,也不⽤关⼼“天书般的通信协议”了。
接⼊模块收到⼀个消息后,通过rpc或者mq来进⾏对接推送到业务模块。
业务模块下发消息给⽤户时,怎么知道⽤户处于接⼊模块的那⼀个实例服务(接⼊模块肯定是有多个实例同时运⾏的)
推送时,可以在⽤户上线时维护⼀个全局uid到接⼊⽹关的映射来做定向推送,对于超⼤或直播互动场景可不区分某⼀个⽤户落在哪个接⼊⽹关,⽽是让所有⽹关获取后来下推连到本机⽤户。
IM特点
实时性
办理护照的程序
即时消息被⼴泛应⽤于各种社交、互动领域的基本前置条件:
如果通过聊天,对⽅半天才收到消息,基本上就是备胎不想再聊了
直播时,如果主播的互动消息房间⾥的粉丝要等很长时间才能收到,也很难让粉丝们有积极参与的欲望
可靠性
不丢消息
“丢消息”是互动中让⼈难以接受的Bug,某些场景下可能导致业务可⽤性差,甚⾄不可⽤的情况。⽐如直播间“全员禁⾔”的信令消息丢失,就可能导致直播室不可控的⼀些情况。海上繁花结局是什么
消息不重复
消息重复不仅会对⽤户造成不必要的骚扰和困惑,可能还会导致⽐较严重的业务异常,⽐如直播间“送礼物”的消息由于某种原因被重复发出,处理不妥的话可能会导致⽤户损失。
⼀致性
同⼀条消息,在多⼈、多终端需要保证展现顺序的⼀致性。
单聊场景
李小萌王雷⼀致性是指希望发送⽅的消息发送顺序和接收⽅的接收顺序保持⼀致
⼀个的某⼀条消息
希望⾥其他⼈接收到的消息顺序⼀致
同⼀⽤户的多台终端
希望发送给这个⽤户的消息在多台设备上也能保持⼀致性。
多端同步的。 收到消息⼀般先落db,然后写离线buffer。db全量,buffer定长或者按时间过期。redis和pika⼀般⽐较适合做离线buffer,mysql和hbase⼀般⽤于消息的db存储。
主持人李晨老婆赵琼
安全性
数据传输安全
数据存储安全
消息内容安全