海量用户IM聊天室的架构设计与实践
本文由网易云信资深服务端开发工程师曹佳俊分享,本文收录时有内容修订和重新排版。
1、引言
聊天室是一类非常重要的 IM 业务形态,不同于单聊和群聊,聊天室是一种大规模的实时消息分发系统。聊天室有多种技术实现方案,业界也有一些开源的实现,每种实现都有自己的特点和应用场景。
本文将分享网易云信针对海量用户IM聊天室的架构设计与应用实践,希望能带给你启发。
2、本文作者
曹佳俊:网易云信资深服务端开发工程师,中科院研究生毕业后加入网易,一直在网易云信负责 IM 服务器相关的开发工作。对 IM 系统构建以及相关中间件的开发有丰富的实战经验。
3、聊天室整体架构
首先,我们先来看一下网易云信当前聊天室的详细技术架构,以及我们在架构升级优化过程中做的一些事情。
如下图,是网易云信聊天室的技术架构:
主要包括以下部分:
1)接入层的 ChatLink;
2)网络传输层的 WE-CAN、WE-CAN bridge;
3)调度层的 Dispatcher;
4)服务层的 Callback、Queue、Presence、Tag、History 等;
5)CDN 分发层的 CDN Manager、CDN Pusher、CDN Source。
下面,我们针对每一层展开详细分析。
4、聊天室的接入层
接入层根据客户端的类型不同会有不同的实现,例如常见客户端(iOS、Andriod、Windows、Mac 等)基于私有二进制协议,Web 端基于 Websocket 协议实现。
接入层作为距离客户端的最后一公里,其接入速度、质量以及数据安全都是至关重要的,下面我们逐一讨论。
1)接入速度和质量:
目前我们搭建了覆盖全国各省份以及全世界各大洲的边缘节点,缩短最后一公里,减少不确定性,提升服务的稳定性。
2)数据安全:
基于对称+非对称加密,客户端与服务器之前实现 0-RTT,完成秘钥交换和登录,同时也支持 RSA/AES/SM2/SM4 等各种加密算法。
接入层除了接受来自客户端的请求,还负责进行消息的单播和广播,因此接入层需要管理本节点的所有长连接,包括每个聊天室房间的连接以及每个连接的标签属性。
此外接入层会上报自己的负载信息给后端服务,方便调度层进行合理的调度。
当流量洪峰来临时,因为需要进行消息的广播,接入层往往是压力最大的,为了保证服务的稳定性,我们做了很多优化策略。
3)自适应的流控策略:
单机流控:接入层服务会监控本机整体的网络带宽使用情况,并设置 2 个阈值 T1 和 T2,当带宽使用率超过 T1 时,触发流控,如果进一步超过了 T2,则不仅触发流控还会不断的调整流控的强度。最终的目标是使带宽使用率稳定在 T1 和 T2 之间。
单连接流控:除此之外,接入层服务还会记录每个长连接的消息分发速度,并进行细粒度的调整,避免单机粗粒度流控导致单个连接分发过少或者过多,做到消息分发的平滑,即减少了带宽流量的波动尖刺,也改善了端侧的体验。
4)性能优化:
ChatLink 高负载运行时,除了网络带宽,调用链路上的各个环节都可能成为性能的瓶颈。我们通过减少编解码的次数(包括序列化、压缩等)、多线程并发、减少内存拷贝、消息合并等多种方式,显著地提升了服务性能。
5、聊天室的网络传输层
我们的IM聊天室系统最初的架构是将接入层和后端服务层都部署在同一个机房的,大部分用户都是直连 BGP 机房的 ChatLink,对于偏远地区或者海外,则通过专线的方式部署代理节点完成加速。
该方案存在明显的缺点就是服务能力上限受制于单机房的容量。此外,专线也是一笔不小的开销。
在我们接入 WE-CAN 大网后,接入层 ChatLink 可以做到客户端就近接入,提高服务质量的同时降低了成本。此外,多机房的架构也使得我们的服务能力上升了一个台阶。
为了适配 WE-CAN 大网,我们设计了 WE-CAN Bridge 层,作为大网接入协议和聊天室协议的桥接层,负责协议转换、会话管理、转发接收。通过这种分层架构,接入层和后端业务层可以少修改或者不修改,减少对已有系统的改造成本,也降低了架构升级带来的风险。
什么是WE-CAN?
WE-CAN(Communications Acceleration Network)是网易自研的新一代大规模分布式传输网络,WE-CAN的根本目标是建立一个能将任意数据从全球任一点稳定、快速、高效地发送到全球任何其他角落的通用传输网络,且这个网络是架设在公共互联网之上的 —— 即无需借助任何特殊的硬件设备或架设专线,而是通过软件方案来达到目标。
6、聊天室的调度层
调度层是客户端接入聊天室系统的前提。客户端登录聊天室之前需要先获取接入地址,分配服务我们称之为 Dispatcher。
Dispatcher 是中心化的,会接受来自 WE-CAN 和 ChatLink 的心跳信息,根据心跳情况来选择最佳接入点。
调度系统设计主要考虑的是以下两个关键点。
1)调度精度:
调度系统会根据请求方的 IP 判断地域和运营商信息,对比各个边缘节点的所属区域、运营商以及节点本身的负载(如 CPU、网络带宽等)。
此外还考虑边缘节点到中心机房的链路情况(来自 WE-CAN),计算综合打分,并把最优的若干节点作为调度结果。
2)调度性能:
面对高并发场景,比如一个大型聊天室,活动初期往往伴随着大量人员的同时进入,此时就需要调度系统做出快速的反应。
为此,我们会将上述的调度规则以及原始数据进行本地缓存优化。
此外,为了避免心跳信息滞后导致分配不合理引起节点过载,分配服务时还会动态调整负载因子,在保证调度性能的前提下,尽量做到分配结果的平滑。
7、聊天室的服务层
服务层实现了各种业务功能,包括:
1)在线状态;
2)房间管理;
3)云端历史;
4)第三回调;
5)聊天室队列;
6)聊天室标签等。
其中最基础的是在线状态管理和房间管理:
1)在线状态管理:管理某个账号的登录状态,包括登录了哪些聊天室、登录在了哪些接入点等;
2)房间管理:管理某个聊天室房间的状态,包括房间分布在哪些接入点,房间里有哪些成员等。
在线状态管理和房间管理的难点在于如何有效管理海量用户和房间。
由于 PaaS 平台的特性,使得我们可以根据不同的租户来进行 Region 划分,从而做到水平扩展。
此外:由于状态数据有快速变化的特点(短 TTL),当某些核心用户或者某个客户报备了大型活动时,可以在短时间内进行相关资源的快速拆分和隔离。
服务层除了要支持海量客户接入、水平扩展外,还有一个很重要能力,就是需要提供各种各样的扩展性功能来适配客户各种应用场景。
为此我们还提供了丰富的功能,比如:
1)第三方回调:方便客户干预 C 端用户的登录、发消息等核心环节,自定义实现各种业务逻辑(因为涉及到服务调用,而这个调用是跨机房甚至是跨地区的,为了避免第三方服务故障导致云信服务异常,我们设计了隔离、熔断等机制来减少对关键流程的影响);
2)聊天室队列:可以方便用户实现一些诸如麦序、抢麦等业务场景需求;
3)聊天室标签:作为特色功能,支持消息的个性化分发(其实现原理是通过客户端登录时设置标签组以及发消息时设置标签表达式,来定义消息分发和接收的规则。标签信息会同时保存在服务层以及接入层,通过将部分标签计算下推到接入层,节省了中心服务的带宽和计算资源)。
8、聊天室的CDN 分发层
当我们评价一个牛x的IM聊天室系统时,常用的一个词是无上限。
架构支持无上限不代表真的无上限。
一个IM聊天室系统,在逻辑上,各个组成单元都是可以水平扩展的,但是每个服务所依赖的物理机、交换机、机房带宽等都是有容量上限的。因此,能够合理地调配多个地域的多个机房,甚至是外部的其他资源,才能真正体现出一个聊天室系统所能支撑的容量上限。
在我们的聊天室系统中,用户所有的接入点遍布各地机房,天然的将各地的资源进行了整合,所能支撑的容量上限自然高于单机房或者单地区多机房的部署模式。
进一步的:当面临一个更大规模的聊天室,此时如果能利用一些外部的通用能力不失为一种合适的选择。融合 CDN 弹幕方案就是这样一种技术实现方案,它可以利用各大 CDN 厂商部署在各地的边缘节点,利用静态加速这样的通用能力来支持超大规模的聊天室消息分发。
基于融合 CDN 弹幕分发方案,其核心点就是弹幕的分发和管理,这是一个可选的模块,我们内部对此进行了封装,可以根据不同的业务特点来选择是否开启而不需要修改任何业务代码。
在开启融合 CDN 弹幕分发方案的情况下,所有的弹幕广播会划分成两条链路:
1)重要的且需要实时送达的消息会走长连接到达客户端;
2)其他的海量消息则会进入 CDN Pusher,通过各种策略进行聚合后送达 CDN Source。
客户端 SDK 会采取一定的策略定时从 CDN 边缘节点获取弹幕消息。SDK 会聚合不同来源的消息,排序后回调给用户,App 层无需关系消息来自哪里,只需根据自己的业务需求进行处理即可。
如上图,展示了 CDN 弹幕分发链路的消息流转过程。
CDN Manager 负责:
1)管理不同 CDN 厂商的分配策略(登录时会通过长连接下发,且能动态调整)
2)负责管理平台上各个聊天室融合 CDN 模式的开启和关闭;
3)对应的 CDN Pusher 资源的调配和回收。
CDN Pusher 实际负责:
1)接收来自客户端消息;
2)并根据消息的类型、消息的优先级等,组装成以一个一个的静态资源,推给 CDN Source,等待 CDN 回源拉取。
9、大规模场景应用案例
在2020年8月,网易云音乐 TFBoys 的 7 周年线上演唱会就是一个聊天室大规模场景应用的典型案例。
在这场活动创造了 78w+ 的在线付费演唱会的世界纪录,其弹幕互动的实现方式采用了我们基于融合 CDN 弹幕分发方案。
事实上:在筹备环节,我们的聊天室系统达成了 20 分钟完成从 0 到 1000w 在线,上行消息 tps 达到 100w 的性能指标。
如上图:是支持本次活动弹幕分发的架构图,普通弹幕和礼物消息分别通过客户端 SDK 以及服务器 API 到达云信服务器,并最终进入弹幕广播服务,随后分流到长连接和 CDN 上,再通过 pull / push 混合的方式送达客户端。
PS:有兴趣的同学可以深入阅读关于这个案例的技术分享:《直播系统聊天技术(九):千万级实时直播弹幕的技术实践》。
10、聊天室标签应用案例
近年来,随着互联网的发展,在线教育越来越火爆,最近又兴起了“超级小班课”模式。
所谓超级小班课,指的是大型多人课堂与小班互动模式结合。在线直播场景下,文字互动作为其中重要的一环,是IM聊天室的典型应用场景。
但在超级小班课的模式下,常规的IM聊天室系统却存在各种各样的问题,不管是建立多个聊天室,还是单个聊天室进行消息过滤,都存在一些严重的问题。
由此我们开放了聊天室标签功能,完美支持了上述业务场景。
基于聊天室标签:可以灵活地支持聊天室消息定向收发、聊天室权限定向管理、聊天室成员定向查询等个性化功能,真正实现大型直播下多场景的分组互动。
比如:
1)对学生进行分组标签后,方便进行因材施教;
2)分小组讨论,小组间内部讨论和组间 PK 等等。
如上图,展示了超级小班课的一个场景:1 个主讲教师+ N 个互动小班+ N 个助教,所有学生被划分成了一个一个的小班,由对应的助教完成预习提醒、课后答疑、作业监督、学员学习情况反馈等工作,同时又接收来自主讲老师的直播画面,做到了大课的规模,小课的效果。
11、本文小结
以上,就是本文的全部分享,主要介绍了我们构建一个大型聊天室系统的主要技术以及架构原理。
任何系统的搭建都不是一蹴而就的,我们也会继续打磨底层技术,就像引入 WE-CAN 来提升网络传输效果,也会继续丰富完善我们的功能图谱(如独创的聊天室标签功能等)。
12、参考资料
[1] 直播系统聊天技术(九):千万级实时直播弹幕的技术实践
[2] 海量实时消息的视频直播系统架构演进之路(视频+PPT)
[5] 微信直播聊天室单房间1500万在线的消息架构演进之路
[10] 万人群聊消息投递方案的思考和实践
[11] IM中的万人群聊技术方案实践总结
(本文已同步发布于:http://www.52im.net/thread-4404-1-1.html)