一、概念
主题(Topic)
是消息的一级分类,是生产者发送和消费者订阅的基本单位。比如,所有订单消息都发送到Order_Topic
消息队列(Message Queue)
Message Queue是Topic在物理上的分区,是消息存储和传输的实际载体。消息真正被存放在各个Queue中
1、并行性/高吞吐:如果上亿条消息都堆在一个队列里,读写会成为瓶颈。
通过将一个Topic分散到多个Queue中,生产者可以同时向多个Queue发送消息,
消费者也可以同时从多个Queue拉取消息,实现了极致的并行和扩展能力。
2、顺序消息: RocketMQ可以保证同一个Queue内的消息是严格FIFO(先进先出)的。
如果要实现“某个订单的顺序处理”,只需要保证这个订单的所有消息都被发送到同一个
Queue中即可。
Topic是逻辑概念,Queue是物理概念。一个Topic由多个Queue组成,
以实现分布式存储和并行处理。
Consumer Group(消费者组)
生产者向Topic发送消息。消费者需要以Consumer Group为单位来订阅一个或多个Topic。
Topic和消费者组的关系
1、消息分发模式:
集群模式(CLUSTERING): 默认模式。同一个Consumer Group内的多个消费者实例共
同负载消费一个Topic的消息。一条消息只会被发送到该Group内的某一个消费者实例。
这是标准的队列模式,用于负载均衡。
1、广播模式(BROADCASTING): 同一个Consumer Group内的每个消费者实例都
会收到该Topic的全部消息。用于需要所有副本都处理消息的场景。注意同一个Consumer Group下的每个消费都会收到相同的消息。
小结:Group定义了消费者的身份和消费模式。不同的Group订阅同一个Topic,会各自独立地消费所有消息,互不影响。
标签(Tag)
1、一个Topic下的消息可以通过Tag进行二级分类,Tag是消息的二级过滤标签,用于在Consumer端对同一个Topic下的消息进行过滤筛选
2、生产者在发送消息时,可以为消息设置一个或多个Tag
3、消费者在订阅Topic时,可以指定只接收带有某个或某些Tag的消息。语法是 TopicName:TagName,支持通配符*
示例:
Topic: Order_Topic
可能的Tag: create(创建订单), pay(支付订单), cancel(取消订单)
一个只关心支付成功的消费者可以订阅:Order_Topic:pay
一个关心所有订单状态的消费者可以订阅:Order_Topic:*
Tag是Topic下的子分类,目的是让消费者只消费自己感兴趣的那部分消息,
避免接收和处理大量无关消息,提升效率。
二、场景设定-集群模式
Topic: topicA
队列: queue1, queue2(共2个队列)
消费者组1: group1(2个消费者: consumer1, consumer2)
消费者组2: group2(3个消费者: consumer3, consumer4, consumer5)
消息: 生产者发送6条消息: M1, M2, M3, M4, M5, M6
模式: 集群消费模式
第1步: 生产者发送消息
生产者将6条消息发送到topicA。RocketMQ的负载均衡机制会轮询地将消息分布到2个队列中:
queue1: 接收消息 M1, M3, M5
queue2: 接收消息 M2, M4, M6
第2步: 队列分配 (负载均衡)
消费者组1 (group1) 的队列分配:
由于group1有2个消费者,正好对应2个队列,所以:
consumer1← 分配到的队列: queue1
consumer2← 分配到的队列: queue2
消费者组2 (group2) 的队列分配:
由于group2有3个消费者,但只有2个队列,所以:
consumer3← 分配到的队列: queue1
consumer4← 分配到的队列: queue2
consumer5← 没有分配到队列(处于空闲状态,作为备份,比如consumer3挂了就轮到consumer5)
第3步: 消息消费过程
消费者组1的消费情况:
consumer1 消费 queue1 中的消息: M1, M3, M5
consumer2 消费 queue2 中的消息: M2, M4, M6
消费者组2的消费情况:
consumer3 消费 queue1 中的消息: M1, M3, M5
consumer4 消费 queue2 中的消息: M2, M4, M6
consumer5 空闲,不消费任何消息
注意:一个消费者收到某一个队列多个消息时,一定是有序的。这是相对某个队列来说的。
关键特性说明:集群模式特性
集群模式特性
1、同一条消息会被不同消费者组分别消费:M1既被group1的consumer1消费,也被group2的consumer3消费
2、同一消费者组内,每条消息只被消费一次:在group1内部,M1只会被consumer1消费,不会被consumer2消费
负载均衡规则:这个是指Queue和消费者组的实例绑定关系,是如何计算的。
// RocketMQ的队列分配算法大致如下:
int index = consumerIndex % queueCount;
// 其中 consumerIndex 是消费者在组内的序号
// queueCount 是队列总数
重点说下:在集群模式下,Queue和消费者关系是怎么绑定的。
我们假设一个Topic有多个Queue,一个消费者组下有多个消费者实例。在集群模式下,RocketMQ会按照负载均衡策略
将Queue分配给消费者实例。核心点是:一个Queue在同一个消费者组内只能被一个消费者实例占用,但一个消费者实例
可以同时消费多个Queue。
Queue和消费者组内的消费者是通过负载均衡策略绑定的
RocketMQ内置了多种负载均衡策略,默认是平均分配(AllocateMessageQueueAveragely)。
在集群模式下,只有一个消费者组的时候,一个Queue只会分配给一个消费者实例,但是一个消费者实例可以消费多个Queue。
所以,一个消费者实例可以接受多个Queue的消息。
不会出现同一个Queue的消息被分配给同一个消费者组内的不同消费者实例。
因为一个Queue在同一个消费者组内只能被一个消费者实例占用,所以这个Queue的所有消息都会由这个消费者实例处理。
不会出现一条消息给消费者A,另一条给消费者B的情况。
为什么这样设计?因为RocketMQ要保证同一个Queue的消息顺序性。如果同一个Queue的消息被同一个消费者组内的不同
消费者实例处理,那么消息的顺序就无法保证了。所以,RocketMQ在集群模式下,一个Queue在同一个消费者组内只会
被一个消费者实例消费。只有当这个消费者实例宕机了,才会触发重新负载均衡,将这个Queue分配给组内的另一个消费者实例。
举个例子:
假设一个Topic有4个Queue(Q1, Q2, Q3, Q4),一个消费者组Group1有2个消费者实例(C1, C2)。那么负载均衡分配可能
如下:
C1负责Q1和Q2
C2负责Q3和Q4
然后,所有发送到Q1的消息都会由C1处理,所有发送到Q3的消息都会由C2处理。不会出现Q1的一条消息由C1处理,另一条消息由C2处理的情况。
但是,如果消费者组Group1有3个消费者实例(C1, C2, C3),而Queue有4个,那么分配可能是不均匀的,比如:
C1负责Q1和Q2
C2负责Q3
C3负责Q4
或者采用另一种分配策略,但无论如何,一个Queue只会被分配给一个消费者实例。
消费分发图如下

结论:绑定原则
在集群模式下,RocketMQ的绑定原则是:
1、一个Queue只能被同一个Consumer Group内的一个Consumer消费
2、一个Consumer可以消费多个Queue
3、绑定是Queue级别的,不是Message级别的
三、场景设定-广播模式
还是上面的场景,只不过是广播的模式,那么流程是怎么处理的
生产者发送6条消息: M1, M2, M3, M4, M5, M6
广播模式下的消息流程:
生产者将6条消息发送到topicA,这些消息会根据负载均衡策略(默认轮询)被分配到两个队列中。
假设分配结果:
queue1: M1, M3, M5
queue2: M2, M4, M6
在广播模式下,每个消费者组内的每个消费者都会独立消费topicA下的所有队列的所有消息。
对于group1:
Consumer1会消费所有消息:M1, M2, M3, M4, M5, M6
Consumer2也会消费所有消息:M1, M2, M3, M4, M5, M6
对于group2:
Consumer3会消费所有消息:M1, M2, M3, M4, M5, M6
Consumer4会消费所有消息:M1, M2, M3, M4, M5, M6
Consumer5会消费所有消息:M1, M2, M3, M4, M5, M6
注意:在广播模式下,消费者组的概念实际上被弱化了,因为组内的每个消费者都是独立消费全量消息的。所以,
广播模式下消费者组的主要作用可能是为了管理方便,而不是为了负载均衡。
广播模式的消费进度:在广播模式下,消费进度是保存在消费者本地的,因为每个消费者的消费进度可能不同
总结:在广播模式下,每个消费者都会独立消费Topic下的所有消息,所以消息会被重复消费,重复的次数等于所有消费者组内的消费者总数。

总结
总结:消息队列和消费者组都是为了负载均衡(集群模式),消息队列每个Queue都是在均匀的分摊TopIc消息,消费者组里面的多个消费者,也是负载均衡的消费Topic的所有消息。
本文详细介绍了RocketMQ中的消息发送、消费、顺序、延迟、过滤、事务以及存储设计,包括生产者发送、Topic与Queue的关系,消费者消费模式和保证消息完整性的策略。
1193

被折叠的 条评论
为什么被折叠?



