![](https://img-blog.csdnimg.cn/20210610165211578.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5Mjg4NDU2,size_16,color_FFFFFF,t_70)
一.生产消息
一条消息只能由Producer Group中一个实例生产并发送至BrokerServer。
二.保存/传递消息
BrokerServer接收到消息后,会根据消息的Topic(主题)将消息保存至相应的Queue(队列)中。Topic可以理解为消息【键】,而消息中保存的信息便是消息【值】。
Rocket MQ通过Topic来管理Queue,也就是说所有Queue都各自隶属于某个Topic。Topic可以拥有多个Queue(数量可配),如此设计是为了提高并发量,实现负载均衡(多Queue情况下,客户端可并发生产/消费消息)。
消息会被各自保存到一个Queue中。即使Topic拥有多个Queue,但消息最终只会被各自分发给其中一个Queue。
三.消费消息
消费消息的前提是订阅该消息的Topic。Rocket MQ以Consumer Group为单位订阅Topic,订阅后可获取到该Topic下Queue中的消息。虽然Rocket MQ将Consumer分为PULL/PUSH两类,但实际上都是通过Consumer主动拉取的方式获取的消息。
对于消费消息,还需了解【消费模式】的概念。因为根据消费模式的不同,消费消息的实现方式也并不相同。
- 集群消费模式:消息允许被多个Consumer Group订阅,但仅能被各个Consumer Group中的一个Consumer Instance消费;
- 广播消费模式:消息允许被多个Consumer Group订阅,且能被各个Consumer Group中的所有Consumer Instance消费。
集群消费模式
![](https://img-blog.csdnimg.cn/20210610165447340.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5Mjg4NDU2,size_16,color_FFFFFF,t_70)
当Consumer Group订阅了Topic,其下的Consumer Instance会与 Topic下的Queue建立关联,并只消费关联Queue中的消息。当某个Consumer Instance宕机/重启时,其它Consumer Instance会代替工作以确保功能不受影响。建立关联的规则如下:
- Consumer Instance > Queue:选择与Queue等同数量的Consumer Instance并建立1:1关联;
- Consumer Instance = Queue:建立1:1关联;
- Consumer Instance < Queue:建立1:N关联。
因为上述规则,导致如下说法:
【注】对于一个Topic,Consumer Group中的Consumer Instance数量最好与其Queue的数量一致,以求充分利用Queue的同时不浪费Consumer Instance资源。
针对每个Consumer Group,Topic下的Queue都各自维护了一个offset(偏移量)。该变量用于标记Consumer Group在Queue上拉取消息的起始位置,因为不同的Consumer Group在同一Queue上的【消费进度】并不相同,因此在拉取消息时的位置上也有所不同。
广播消费模式
![](https://img-blog.csdnimg.cn/20210610165647740.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5Mjg4NDU2,size_16,color_FFFFFF,t_70)
广播消费模式下,Consumer Group下Consumer Instance会消费Topic下所有Queue的消息。对于这一点可以理解为Consumer Instance会与所有Queue关联并消费消息。
广播消费模式下offset由Consumer Instance本身负责维护(集群消费模式由BrokerServer负责维护)。之所以会产生如此变化是因为BrokerServer以【组】为单位进行数据维护,但在广播消费模式下该单位被细化到了【个体】,这超出了BrokerServer的能力范围。使用Consumer Instance维护offset也有不当之处,比如会很容易造成消息重复。
广播消费模式有诸多不完善之处。虽然能让消息被Consumer Group下所有Consumer Instance消费,但却有诸如容易造成消息重复/消费进度难以维护/不具备消息重投机制等缺点(关于消息重复/消费进度/消息重投等内容会在该系列的其它文章中专门讲述),因此在实际开发中不推荐使用该模式。但如果需解决该类需求,可以使用【伪广播消费模式】。
伪广播消费模式
![](https://img-blog.csdnimg.cn/20210610165815701.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5Mjg4NDU2,size_16,color_FFFFFF,t_70)
伪广播消费模式不是真正的广播消费模式,它由集群消费模式伪装而成。具体操作是,创建多个Consumer Group以集群消费模式订阅同一个Topic,每个Consumer Group中都只有一个Consumer Instance,由此,每一个Consumer Instance都可以消费到Topic下的消息,达到广播集群模式的效果。