基于消息总线的高可扩展性IM系统后台架构设计

Posted 普通程序员

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于消息总线的高可扩展性IM系统后台架构设计相关的知识,希望对你有一定的参考价值。

如果你还不了解IM系统的整体结构,可以先看看《》(一下简称《IM完整设计》)这篇文章。


在《IM完整设计》文章中,服务端的结构是非常简单的,所有逻辑都集中在logic节点。如下图


在实际生产环境下,这种简单结构存在很多弊端。


1、功能扩展性欠佳

逻辑集中在logic一个节点,要上线新功能,只能修改logic再部署,无法实现类似微服务架构的快速部署能力。


2、存在性能瓶颈

由于gate到logic的消息传递采用的同步方式,为了匹配不同节点消息处理能力的差异,需要在logic中维护缓冲区。不同类消息,对消息延迟的容忍度不完全一致,缓冲区需要有不同的区域(或主题)概念。仅靠logic的一点java代码来维护这样的结构不是特别合适。

一个简单的缓冲区结构,会导致处理速度慢的消息拖慢整个消息处理速度!


3、维护成本高

由于所有逻辑集中在logic节点,导致logic节点逻辑复杂,代码臃肿。项目过程中加入的研发人员,需要很好的理解工程代码之后,才能对功能进行修改、维护,上手难度大。

修改任何一个逻辑,都需要回归整个logic节点主要功能,且要将所有功能都重新部署,无形中加大了维护工作量。


为了解决这些问题,引入消息总线(Kafka),系统结构进化为下图。(其中Rest-api模块往下的部分提供http短连接的业务逻辑,不做详细说明。)


1、tcp-gate,websocket-gate是tcp和websocket两种长连接的接入模块。


2、Dispatcher接收来自接入模块的消息,并对消息进行分发。

(1)对于auth,handshake类的需要同步处理的消息,通过RPC调用相关服务进行处理,并及时返回结果

(2)对于一般消息(可异步处理),按照业务(cmdid)不同,分别投递到消息总线的对应主题(topic)


3、单聊、群聊、离线、历史等具体业务逻辑节点从消息队列中获取对应的消息(单聊获取单聊消息),进行相应的逻辑处理,如写数据库、写缓存、计算等。将处理后的结果(或信息)再次放入消息总线(topic为接下来需要处理消息的逻辑节点对应的topic,如Deliver Service)


4、Deliver Service从消息总线接收“单聊”等节点处理后的消息,将消息投递给目标用户。


采用消息总线解耦的结构有诸多好处。


1、高可扩展性

通过消息总线,各个业务逻辑单元(单聊、群聊……)从代码层面完全独立,可以独立部署。当需要修改现有逻辑,只需要修改对应逻辑单元;如果要增加业务逻辑,增加新的业务逻辑单元即可。


2、高性能

(1)Kafka消息总线有充足的缓冲区,并且可以适配逻辑单元处理速度的差异(通过不同的topic区分逻辑单元)

(2)各个接入层节点、业务逻辑单元都可以通过部署节点实现水平扩展,性能线性增长

(3)数据库和Redis缓存都采用hash水平分库,性能能够实现线性增长


3、维护成本低

由于接入层(tcp-gate,websocket-gate,Dispatcher,Deliver Service)功能相对固定,逻辑层的逻辑单元又完全独立,新加入项目的开发人员只需要关注需要处理的逻辑单元即可,上手难度大大降低


上线新的逻辑单元,完全不影响已有的逻辑,对测试资源消耗也得到很好的控制。

这个结构解决了很多问题,但是依然面临挑战。对于公司级的万人大群,大家活跃时,会面临消息延迟的问题。这个问题也是由方法可以缓解的。


相关阅读




普通程序员


长按关注

微信ID:farmerbrag



以上是关于基于消息总线的高可扩展性IM系统后台架构设计的主要内容,如果未能解决你的问题,请参考以下文章

微信后台异步消息队列的优化升级实践分享

超赞!这款基于SpringBoot + Dubbo打造的在线IM系统功能丰富(附源码)

基于RabbitMQ的消息总线架构设计

高并发IM系统架构优化实践

基于消息系统架构设计

后台消息队列处理简易框架