默认

一套高可用、易伸缩、高并发的IM群聊、单聊架构方案设计实践

查看数: 274104 | 评论数: 28 | 收藏 29
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2018-10-17 11:39

正文摘要:

本文原题为“一套高可用群聊消息系统实现”,由作者“于雨氏”授权即时通讯网整理和发布,内容有些许改动,作者博客地址:alexstocks.github.io。应作者要求,如需转载,请联系作者获得授权。 一、引言 要实现一整 ...

评论

JackJiang 发表于 1 年前
引用:一剑开天 发表于 2023-03-16 19:28
美丽的姑娘(深邃的文章),我要娶你(我要研究明白),可你要彩礼200万(需要大量知识储备),终究是我不 ...

还得好好学
一剑开天 发表于 1 年前
美丽的姑娘(深邃的文章),我要娶你(我要研究明白),可你要彩礼200万(需要大量知识储备),终究是我不配(真心读不下去)
egojit 发表于 2 年前
我broker把同一个房间的消息只发送一次到同一个gateway,然后由gateway负责把消息发送给所有在这个房间的客户端,那gateway如何知道哪些连接属于哪些房间?redis?那每条消息都读redis?性能损失是不是很大?
JackJiang 发表于 2 年前
引用:wzq1915414095 发表于 2022-01-16 21:45
请问如果按照这个架构实现群聊,那是不是同一个群(room)的用户都得连接同一个Gateway

不是,如果是这样,那架构的限制就很大了
wzq1915414095 发表于 2 年前
请问如果按照这个架构实现群聊,那是不是同一个群(room)的用户都得连接同一个Gateway
JackJiang 发表于 2 年前
引用:15805817394 发表于 2022-01-06 15:32
一看这种又有详图,又有大段文字说明的,就知道是精品,每一行字都是宝贵的知识和技巧

识货!
15805817394 发表于 2 年前
一看这种又有详图,又有大段文字说明的,就知道是精品,每一行字都是宝贵的知识和技巧
JackJiang 发表于 4 年前
引用:mark_lin 发表于 2020-06-03 23:10
感谢分享~
Gateway既然持有client的长连接,而Broker又只是把消息发送到Gateway,并由Gateway分别发给连接 ...

说到底,kafka是特定领域的特定实现,而Proxy+Broker+Router其实是根据自已的整理技术架构和算法逻辑进行的实现,前者官方开发出的是什么东西你就只能那么用,无法进行匹配性的修改,而后者显然可以发挥的空间更大。总之一句话,im这种东西很难标准化,也导致了如果某些核心部分用标准化组件的话,那你根据整体架构和整体算法来调整的空间就没有,结果就是,那东西虽好,但可能并不能很好的匹配你的算法需求
mark_lin 发表于 4 年前
感谢分享~
Gateway既然持有client的长连接,而Broker又只是把消息发送到Gateway,并由Gateway分别发给连接的client,为什么broker还要保留用户的登录状态?
如果仅是群聊系统的话,Proxy+Broker+Router是否也值得由kafka来替换,其中Gateway负责转发消息给所有在线的用户。PS:看过JackJiang写的关于MQ用于即时消息系统的文章,但如果仅限于群聊系统的话,感觉kafka可以简化很多,不知我这个想法是否真的简化可行?
JackJiang 发表于 4 年前
引用:登至必极 发表于 2020-04-28 14:57
还有一个问题就是,服务的可用性怎么保证?也就是一旦某种类型的某个服务比如borker中的某个replica挂断, ...

集群的另一个优势就是高可用,这个服务不可用了,客户在重连逻辑下就连到别的实例了。
登至必极 发表于 4 年前
还有一个问题就是,服务的可用性怎么保证?也就是一旦某种类型的某个服务比如borker中的某个replica挂断,怎么进行故障恢复对终端无感知呢?谢谢大佬解答
JackJiang 发表于 4 年前
引用:登至必极 发表于 2020-04-27 21:48
看了一下文章,确实很有深度,但是搞不明白的一点是,消息从gateway发出,client如何获取到呢?这块没衔接 ...

client就是通过长连接连到gateway的
登至必极 发表于 4 年前
看了一下文章,确实很有深度,但是搞不明白的一点是,消息从gateway发出,client如何获取到呢?这块没衔接起来,望大佬指点一下。
JackJiang 发表于 5 年前
引用:yuyu 发表于 2019-03-02 17:56
逐个回复你的问题。
1 写扩散点最后确实是在 Relay。
2 以系统最后一个版本为例,Router 是向系统的 Br ...

感谢作者的详细回复!
yuyu 发表于 5 年前
引用:一夕 发表于 2019-03-01 16:06
有一点不是很明白:
1.是不是写扩散点逻辑在最后的方案中是放在【Relay】中。
2.【Route】和【Relay】的 ...

逐个回复你的问题。
1 写扩散点最后确实是在 Relay。
2 以系统最后一个版本为例,Router 是向系统的 Broker  转发群内每个在线用户的在线信息【Gateway Message】,向 Relay 转发每个在线用户所在的 Gateway信息【Relay Message】。Router向Relay发送消息,Relay不会向Router发送消息,只会向 Gateway 发送群聊消息【Room Message】和单聊消息【Chat Message】。

或许举例一个实际场景能够更让人清晰明了。譬如有如下场景:

A: Room1 【RoomID: 100】内有用户 U1【UID:1001】、U2【UID:1002】和 U3【UID:1003】;
B:U1 登录了 Gateway1【G1】,Gateway1 的地址为 10.0.0.1:10000;
C:U2 登录了 Gateway2【G2】,Gateway2 的地址为 10.0.0.2:10000;
D:U3 不在线。

则 一条Gateway Message 包含的数据关系就是:map{key: Room1-100,value: User List[U1-1001,U2-1002]};

Relay Message有两条,其数据关系分别是 map{key: U1-1001, value: G1-10.0.0.1:10000} 和  map{key: U2-1002, value: G2-10.0.0.2:10000} ;

Room Message 就是一条包含 Room1-100 的消息;

Chat Message 就是两条分别包含 U1-1001 和 U2-1002的消息。

3 本系统其实讲了两个模型的系统:第九章内容讲解的最新版本的实时在线消息下发系统以及第八章内容讲述的异步离线消息下发系统,前者是使用推技术把消息【推送】给客户端,后者则是依赖客户端自身的状态把消息【拉取】下来。

离线消息系统中并没有 Relay 模块,只实现了群聊消息的异步下发,所以请明晰概念后再进一步讨论。
yuyu 发表于 5 年前
引用:coding_im 发表于 2018-12-07 18:56
请教几个问题。
1. 用户发的消息怎么进入系统,我看里面的client并不是指用户?  用户与gateway保持长连 ...

这个消息系统仅仅是一个消息下发通道,可类比为一种pubsub型的mq,如果下发消息是群消息,则这个系统根据群ID就能把消息准确的扩散复制后下发给群里每个相关成员的客户端,如果消息消息是单聊消息,则这个系统根据消息中的UID就能准确地把消息下发给这个UID的客户端。

下面逐个回答你的问题:
1 这里的client其实是服务器其他模块对这个系统的调用者,套用mq中的术语,其为producer。用户与gateway之间确实保持长连接,这个连接其实是用于上传客户端发送出的消息,也用于接收别的客户端发送来的消息,但是这套系统重点讲解的是如何对消息进行下发,所以本文只讲了如何对消息进行扩散、寻路(路由)和下发。

2 如果一个 RoomID 的所有客户端都连接一个 Gateway,则你说的这个问题确实存在。但是,这里的问题是如何避免这种情况发生,而不是把问题抛给消息系统,把压力传递给消息系统让消息系统去解决这个问题。譬如,我们在Gateway前再加一个 httpDNS 系统,当客户端寻找要连接的 Gateway 的时候,由 httpDNS 系统确保所有的客户端连接均匀地被打散到各个 Gateway,同时限制每个 Gateway 的连接数目不会超过最大 Room 内成员额定数【譬如最大 QQ 群是2000人,则确保每个 Gateway 的连接数低于 2000】,这个问题估计就不是个问题了?

上面是个人的愚见,还有需要指教的地方,可以继续回帖。

点评

JackJiang  说:
yuyu是本文《一套高可用、易伸缩、高并发的IM群聊架构方案设计实践》的作者,专门请他来回复的,以他的回答为准,大家可以多讨论  (5 年前)
一夕 发表于 5 年前
有一点不是很明白:
1.是不是写扩散点逻辑在最后的方案中是放在【Relay】中。
2.【Route】和【Relay】的区别是什么,介绍中感觉【Roter】只是负载维护用户和群的映射关系的管理工作。按道理【Route】与【Relay】应该是有交互的,图中没有体现。那【Relay】如何获取写扩散的映射关系,用户和群的关系。
3.【Broker】是不是最后只负责抽取【PI】【XIU】中存储的消息进行数据转发给对应的【Relay】
coding_im 发表于 6 年前
请教几个问题。
1. 用户发的消息怎么进入系统,我看里面的client并不是指用户?  用户与gateway保持长连接,这个连接只用于用户接收消息吗?
2. broker会转发消息给跟roomID有关系的gateway。若一个gateway跟所有roomID有关系,是不是从client发出的所有消息都会转发到这个gateway,这样gateway要出处理这个系统所有消息,会不会有瓶颈?
65725738 发表于 6 年前
引用:yuyu 发表于 2018-11-04 00:46
逐个回答你的问题。

1 关于到底用tcp还是udp,这个话题跟你们公司相关基础设施建设有关。

七、Router需要进一步强化

7.1、简述

当线上需要部署多套群聊消息系统的时候,Gateway需要把同样的Room Message复制多份转发给多套群聊消息系统,会增大Gateway压力,可以把Router单独独立部署,然后把Room Message向所有的群聊消息系统转发。

这里面没理解。gateway 为什么需要复制多份Room Message。然后为什么要把Router单独独立部?
65725738 发表于 6 年前
引用:yuyu 发表于 2018-11-04 00:46
逐个回答你的问题。

1 关于到底用tcp还是udp,这个话题跟你们公司相关基础设施建设有关。

不好意思 。谢谢解答。但是还是没太明白。  你说 所有图中的 Client 指的是服务端的消息发布者,并不是 APP 类型的客户端。  这个没问题。   我的意思是如果是使用tcp长连接的话。   gateway就是 app客户端连接的服务端。那么它本身不就是你的 图中的 Client 吗?

至于我第4个问题。我意思组件之间是用什么技术通信的。 http,tcp长连接,tcp短连接。rmi 还是什么?

大佬你在一群,我现在加群是四群。所以只能在这里问你了。

返回顶部