一. 自定义属性介绍和利用场景
在挪动互联网高速倒退的新时代,IM 即时通讯失去了疾速的倒退。IM 中除了传统的图文聊天,在线秀场、在线教育、直播带货、游戏互动等场景利用也越来越宽泛。特地是一些一线主播的直播中,直播间动辄几万甚至几十万上百万人同时观看,这对 IM 的通信并发能力提出了更高的要求。
融云作为 IM 即时通讯和音视频通信云服务的代表,提供了直播聊天室 SDK 和音视频直播 SDK。而在提供这些根底性能的时候,业务层可能也须要设置一些本人的属性,比方在语音直播聊天室场景的会场属性同步,主播麦位信息、角色治理等等,亦或者狼人杀等卡牌类游戏场景中记录用户的角色和牌局状态等。这些自定义属性都能够丰盛整个 IM 的业务状态。
在本篇文章中我重点介绍以聊天室为背景的超大并发规模下,是如何实现这些自定义属性的设置以及散发的。
二. 海量用户下面临的技术挑战
聊天室和一般的 IM 群相比最大的不同点在于它是一个虚构的组织,聊天室是无界的,所有的人都能够随便的进出聊天室;而群更像一个房间,它是一个有界的、有下限的私密组织。而随着直播行业的蓬勃发展和观看直播人数的与日剧增,直播房间的聊天室更容易呈现那种超高并发场景,例如一线主播直播间的聊天室。
自定义属性在进行了设置后,须要及时的将这些属性同步到聊天室中的各个端上。在这个过程中最大的挑战是在散发上。因为如果聊天室人数巨多,而且很多场景自定义属性是具备时效性的,所以及时的将自定义属性同步到各端就很考验服务的高并发场景下的散发能力了。
三. 高并发下自定义属性设置与散发实现
在分布式系统架构中,为了对立聊天室的行为,咱们会利用一致性 hash 将同一个聊天室的所有信令汇聚到一个实例上。这样做是有肯定益处的,比方能晋升服务的缓存命中率,像聊天室人员进出黑 / 白名单设置和判断等都能够利用内存中的缓存,不必每次都拜访第三方缓存,从而进步了聊天室的响应速度。然而这样带来的问题就是,如果聊天室人数过大,聊天室的散发能力会是零碎的瓶颈,而且一旦单台主机下发能力达到下限,是无奈通过扩容来解决问题的,因为不管怎么扩容,一个聊天室的所有信令还是会汇聚到这个实例中。
为了晋升服务的散发能力,咱们独立出一套独自的散发服务(聊天室音讯服务),具体如下图所示:
在这套架构零碎中,咱们将聊天室零碎分为聊天室服务以及聊天室音讯服务,聊天室服务的作用仍然是接管聊天室相干的所有上行信令,比方人员进出,自定义属性设置等等。而聊天室音讯服务更专一聊天室音讯以及自定义属性等的散发。
用户在退出聊天室后,须要依据用户本身的 ID 进行一致性 hash 来算出须要落在哪个聊天室音讯服务中,并进行退出。这样一个聊天室的用户就会被均匀扩散到了聊天室音讯服务中。这样做也解决了零碎遇到压力后不能扩容的问题。在自定义属性同步到聊天室音讯服务上后,散发节点须要将属性搁置到内存中,而后给以后节点的所属用户发送一个告诉拉取的信令,客户端在收到告诉拉取信令后进行自定义属性的拉取。
四. 自定义属性的内存存储和客户端疾速拉取
在聊天室音讯服务接管到自定义属性变更申请时,会将这份数据保留到全量属性汇合里,这个汇合里存的是所有的自定义属性汇合,如果这份数据被 LRU 淘汰掉或者服务重启的话,会从第三方缓存中从新构建一份数据进去。
内存中的全量数据,比拟适宜于刚退出聊天室的人,他们退出聊天室后间接拉取这些全量数据即可。然而如果曾经在聊天室了也曾经拉取过全量属性的话,这时聊天室再设置了新的自定义属性或者删除了某一个自定义属性的话,如果客户端想晓得方才的自定义属性的行为,就须要对客户端的全量自定义属性与服务器端自定义属性进行比对。不论比对行为是放在服务器端还是放在客户端都会减少肯定的计算压力。为了解决增量数据的同步,咱们构建了一份属性变更记录的汇合,具体如图所示:
属性变更记录采纳的是一个有序的 map 汇合 .key 为变更工夫戳,value 里存变更的类型以及自定义属性内容,变更的类型次要为设置和删除。这个有序的 map 提供了这段时间内所有的自定义属性的动作,客户端在收到自定义属性变更拉取的告诉后,带着本人本地最大自定义属性的工夫戳上来拉取,例如图中场景,客户端传的如果是工夫戳 6,则会拉取到工夫戳为 7 和工夫戳为 8 的两条记录。客户端拉取到增量的内容后在本地进行回放,而后对本人本地的内容进行相干的操作即可。
五. 结束语
文章大体解析了融云聊天室的基础架构以及在此架构下,如何做到了超大规模并发下的自定义属性的设置和散发。而随着互联网的高速倒退,自定义属性的设置利用会越来越宽泛,而并发规模或者会持续晋升,届时咱们的架构也会迭代,持续为客户提供低延时高牢靠的服务。