在 IM 系统中,“用户状态” 通常指用户的离线和在线状态;在一些企业 IM 系统应用中,会对用户的状态进行扩展,比如:“会议中”、“疯狂编码中”、“发热中” 等等;对于前一类用户状态,只需要缓存中记录即可,而对于后一类的用户状态,则需要进行持久化。
在很多的业务场景中,客户端用户特别关注其联系人的在线和离线状态;还记得那些年我们曾每天都会登录的 QQ 吗?通过好友头像的亮度,就知道对方是否在线。
对于客户端用户来说,其好友联系人的在线状态,是怎么同步过来的呢?这一部分内容不是很复杂,我们今天分析一下。
一、IM 部署模型
IM 系统从产生到现在,在这几十年的发展过程中,共有两种部署模型:一种是介绍人模型,一种是代理人模型,见下图。
介绍人模型,也叫直连模型,在服务端的帮助(介绍)下,客户端会直接建立连接进行通讯;这种 IM 模型在 IM 系统最初发展时或在局域网中应该较多,目前在互联网系统中几乎不再应用。
代理人模型,也叫推拉模型,客户端之间的通讯全部由服务端进行代理,因此服务端是一个非常非常关键的角色;目前绝大多数的 IM 系统都采用代理人模型。本 IM 专题所有的文章和实践也全部是基于代理人模型进行讲解的。
二、消息同步模型
在代理人模型中,所有客户端的状态(用户登录之后,即为在线;用户登出或心跳超时,即为离线)都会第一时间同步到服务端,具体来说,在分层架构 IM 系统中,用户状态是同步和保存到路由层的 Router 中。现在问题的关键是,保存在服务端的所有用户的状态数据,如何同步到相关的客户端?
总的来说,有两种实现方式:一种是信箱模型,一种是电话模型;信箱模型在单体架构的消息收发逻辑中分析过(见 IM专题:单体架构IM系统(2)),电话模型在分层架构的消息收发逻辑中分析过(见 IM专题:分层架构IM系统(12)—消息收发逻辑实现)。见下图。
信箱模型和电话模型都是将消息从服务端同步到客户端的方式。
信箱模型,也叫做 pull 模型,动作由客户端触发,服务端只管实现接口和被动响应即可;信箱模型中,由客户端对结果负责。信箱模型落地实现非常简单,但是消息的及时性不高。
电话模型,也叫做 push 模型,动作由服务端触发,客户端收到消息后,需要回复确认;电话模型中,由服务端对结果负责。电话模型在落地实现时具有一定的复杂度,但是消息的及时性很高。
对比两种实现模型,优缺点正好相反;大家思考一下,有没有第三种模型能中和信箱模型和电话模型,集其优势于一体呢?(我们在后续文章中进行分析)
三、同步用户状态
用户状态从服务端到客户端的同步,适合采用信箱模型进行实现。
基于信箱模型同步用户状态,服务端实现时更容易落地;而且,从产品上讲,用户对联系人在线状态的敏感度远没有消息那样强,所以用户状态同步的及时性不需要很高。
如果同步用户状态采用电话模型,除了实现的复杂度之外,对服务端会造成 “写扩散” 的负载:假设平均每个用户有 30 个联系人,在一秒内有 2000 个用户的状态发生了改变(从离线变为在线,或从在线变为离线),那么服务端需要推送 60000 次。
采用信箱模型的话,则可以通过批量读取的方式,避免扩散操作。见下图。
客户端与服务端之间的交互,复用 “心跳链路”;心跳除了保活客户端与服务端之间的长连接外,可以通过扩展成为信箱模型的通信链路,用于获取联系人状态,用户签名,非实时的广播消息等业务场景。
客户端在心跳请求(也即获取用户状态请求)中,加入联系人 uid 列表参数;请求由入口层 Entry 接收后,转发至 业务逻辑层 Logic; Logic 对路由层 Router 进行批量读取,获取联系人列表的在线状态,然后逐层返回。
关于用户的在线状态,这里有一个非常关键的点需要注意:用户往往只关心联系人最后的在线状态,对中间状态的变化(在线变离线,或离线变在线),并不关注;也就是说,用户状态是时序性不敏感的业务;如果采用电话模型的话,会体现出这种时序性,很可能会由不稳定的网络造成误差。
例如:用户 uid=102,在 15:16:17 时,由 ”离线“ 变为 ”在线“;在 15:16:18 时,又由 ”在线“ 变为 ”离线“;用户 102 最后的状态是 ”离线“。 在信箱模型中,直接拉取最后的状态即可。但在电话模型中,需要由服务端向客户端推送两次数据:一次是 ”在线“,一次是 ”离线“,这两次推送很可能会因网络抖动导致 ”离线“ 数据先到,”在线“ 数据后到,最后 uid=102 的用户状态是 ”在线“,从而产生错误的用户状态。
最后,总结文中关键:
- IM 系统有两种部署模型:一种是介绍人模型,一种是代理人模型;
- 代理人模型的 IM 系统,消息从服务端同步到客户端,有两种常用方式:一种是信箱模型,一种是电话模型;(第三种模型后续介绍)
- 分层架构的 IM 系统,同步用户状态宜采用信箱模型,基于心跳通讯链路进行实现。
作者:棕生 | 来源:公众号——架构之魂
版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。