开发者学堂课程【高校精品课-厦门大学 -JavaEE 平台技术:RocketMQ架构】学习笔记,与课程紧密联系,让用户快速学习知识
课程地址:https://developer.aliyun.com/learning/course/80/detail/15954
RocketMQ架构
Rocket MQ 的架构,从架构上来说,Rocket MQ 分为四个部分,就是我们前面说的生产者和消费者,是两组独立的机器。
那在服务器端,它主要是分为这个 name server 和 broker这两个部分。
broker 是r ocket MQ的核心的模块,所有的这个消息的存存储,处理,分发,都是
由这个broker来负责的。
所以为了保证这个 broke的这个高可用性和它的这个性能,我们可以在整个系统中间配属多个 brokker,那所有的 broker都可以配属一个组中的结构,就是一台主
broker,一台这个从 broker,那当主 broker挂掉以后,消费者就会去消费这个从broker。
这样使得说发送上去的这个消息都会确保会被消费掉,在整个 broker集群中间,我们所有的这个主 broker之间其实是相互独立的,他们不会去做数据的交换,他们之间的这个协调靠的是我们的这个 name server,所以 broker在启动的时候都需要把自己注册到一台或者多台这个 name server上,然后每隔三十秒钟就像这个 name server上头去发一个他的topic的信息,就是在我这个 broker里头到底有些什么样的topic 的信息,我们称之为 topic的路由信息,发到这个 name server上,那 name server就是成了这个注册中心,所有的 broker都在启动的时候需要去在name server上去注册的,而且每隔三十秒钟都需要发送自己的 topic的路由的信息的,无论生产者和消费者要去发送消息,还是要去获得消息,都是从这个 name server上
去做查询的。
为了保持这个系统的稳定性,在我们的整个系统中间,我们可以架设多个 name server,但是 name server之间其实是互不通信的。如果你嫁了多个 name server,那在这个 broker上面,其实是每一台broker都要设定自己的一个 name server的主,所有的 name server都无法感知它们的存在。
broker去跟每一个 name server去保持这样的一个连接和心跳,消息的这个生产者是我们前面说的它是用来产生消息的,那它是通过这个name server来获取所有的broker的这个topic的信息 ,觉得 topic在哪些 broker上面 然后根据这个负载平衡的原则,来选择那么 server中间的某一个 name server的节点,去保持一个长链接的这样的一个连接,来定时的去查询这个 topic的配置信息,但如果说一个 name server去挂掉了,他都会他自己列表中间去自动选择下一个 name server,直到有连接为止,并自动建立这样的一个长连接,每个这个生产者会跟他关联的所有的主
的 broker去保持一个长链接,
因为当他发送消息的时候,它其实会发送到其中任何一台 broker上面,当每一次发送成功以后,为了使得所有的 broker的负载得到均衡,它在下一次的时候一般会选择另外一个 broker去发送,这样使得所有的消息被均匀地发送到所有的这个broker上面。那对于消费者来说,他同样是从 name server上去获取这个 topic的相关的信息,就是 topic在哪一些 broker上面,同样他也要跟这个 name server去保持长
连接,因为他要不断的去获取新的这个 topic的相关的信息。
那同样如果说它连接的那个 name serve挂掉,他都会立马中间选择下一个 name server连接,直到找到能够使用的 never把他接上,保持这样的一个连接。那通过name server,他可以拿到所有 topic的。在哪些 broker上面,我们称之为 topic的路由信息,然后它就会像这些 broker去发这个破的请求,去获取这个消息的数据,单个的这个消费者和他关,他会跟所有的这个 broke去保持一个长连接,并维持这样的一个心跳,那如果说失去了这样的一个心跳以后,那他就会向消费者的其他的这个同组里头的其他的消费者发发送这个通知,把原来分发给这个消费者的这个消
息,再去重发给另外一个同组中间的另外一个这个消费者。
Topic 是这个在消息队列中间的概率模型中间最重要的一个概率模型,但是实际上他是一个消息的逻辑分类,就是在我们的消息服务器上头,它的物理的结构其实不是以 topic,那一个 topic其实是可以分布在多个 broker上面,它并不限制在某一台服务器上,我们称之为在一个 broker上面的这个 topic的子集,称之为一个topic的分片。其实在每一个这个分片的里面,他的消息的物理的存储结构是这个队列 以队列的方式来存放的,我们可以默认设定说每一个 topic的分片有多少个队列,默认的话是四个,当然我们可以在 broker的配置文件中去配,这样的一种这个队列的存在的方式,是我们这个 rocket mq的一个最基本的消息的处理方式,所以说称之为基于这个消息队列的这样的消息服务器,那当一个 broker被创建的时候,他的分片创建的时候,它的这个队列就会创建出来,那这个队列的这个存在,为什么会创建多个队列,因为他是我们消息的资源分配的一个最基本的资源,比如说我们在一个 topic里头有五个队列,在一个消费群组,有两个消费者,在 topic中间里的队列会平均的分给消者,所以在物理上头真正实现的时候,我们在这个消费者中有两个
消费者,第一个消费者获得三个队列,第二个消费者获得两个对列,那就意味着说,当发到前面三个队列,中间的消息会发给第一个消费者。
后面两个队列中的消息会发给第二个消费者,这是在集群消费的情况下头,如果说
是网络消费的话,是所有的队列都会发给所有的这个消费者,所以在集群消费上头,这个队列就成了我们做这个消息分发的一个最基本的这样的一个模型。
所以在设计的时候也要注意一下,我们的消费者应该是小于这个队列的数量,那如果说消费者大于消费者的数量大于队列的数量,就会有消费者其实没有分到任何队列,那他也不会收到任何的消息。最后我们说一下消息,消息是我们在消费中的载体,一个消息里头是被分发给一个 topic, topic 相当于他的这个寄信的地址,在物理存储上的物理的船上,他会被发到topic里头的一个队列里头。所以在发消息的时候,我们需要给消息指定一个 topic,当然我们在 topic上面也可以指定一个tag,这个 tag的目的是做一个过滤,也就是我们在消息的队列里头是按照先后顺序
调到队里得去的。但是我们可以上面加一个 tag,使得这个消费者在消费这个队列中间的消息的时候,有选择性的去选择其中的某一部分的消息去做消费。
我们用一张图把我们前面说的这几个概念把它总结一下,这张图里头既包括了生产者消费者,也包括了我们的匿名服务器,broker,还有我们的这个队列和 topic。我们前面说的这些概念都在里头,我们在生产者这边主要有两个生产者,一个是生产者主A和主B,那中间的话是两个这个分布式的 broker,broker 是两台实际的设备,存储了我们开了两个 topic A和B,那其中 topic A我们定义了四个队列,这是默认的,那他的三个队列是在这个 broker A上面,一个队列是在 broker B上面。Topic B的话,我们里头有两个队列,都在这个 topic B上面,那右边的话,我们有两个这个消费者组,消费者主A的话,是以集群消费的方式来定义了这个 topic的A,所以说在 topic A里头的这个四个队列责备均匀的分给了在消费组组 A中间的两个消费者,每个消费者有两个对立,组 B则是以广播消费的方式来订阅了 topic B。所以我们可以看到 topic B中间的两个队列都会关联到这个组B中间的两个消费者。所以组B在部署这个 rocket MQ的时候,我们要把这些东西全部被他跑起来,是要有一定的先后顺序的。
我们最先要启动的是这个 name server,把 name server启动成功了以后,我们再来启动 broker,在启动的时候需要指定这个 broke注册到哪一个 name server上头去。那当把broker启动完成了以后,我们再来运行这个生产者和这个消费者。
生产者在启动的时候,它首先会连到一个 name server,获取这个name server上面的所有的 broker地址。所以说对于生产者那边,他并不需要知道 broker是谁,
但他需要知道 name server的地址和端口,他拿到了这个 broker以后,再跟 broker建立连接,然后就会往所有的 broker上面去发送信息。
生产者,只会跟一个 name server去做连接,但是他会跟所有的 broker建立连接,这样的话会获得会向所有的 beoker上面去发自己的这个心跳的数据。
然后他会轮流的指定去发送数据,但消费者的话,同样在启动以后,从name server上得到这个broker的路由,然后去订阅这个 broker上面的这个 topic,那我
们知道他会把这个broker的队列分配给这个消费者。
所以生产者那边如果说发送一条消息被放到了某一个队列中间,那订阅了这个topic
的就分配到 broke这个消费者,则会收到这个消息去处理它,这就是我们这个rocket MQ 的这个消息服务器的一些最基本的这个消息发送和接收的机制。