RocketMQ基本概念!
RocketMQ基本概念!
月伴飞鱼官网:https://rocketmq.apache.org/
中文文档:https://github.com/apache/rocketmq/tree/master/docs/cn
最佳实践:https://github.com/apache/rocketmq/blob/master/docs/cn/best_practice.md
设计文档:https://github.com/apache/rocketmq/blob/master/docs/cn/design.md
Topic:
一类消息的集合,消息发送者将一类消息发送到一个主题中。
例如订单模块将订单发送到
order_topic
中,而用户登录时,将登录事件发送到user_login_topic
中。
标签(Tag):
消息设置的标志,用于同一Topic下区分不同类型的消息,可以根据Topic+Tag实现消息的精细化生产和消费。
ConsumeGroup:
消息消费组,一个消费组拥有多个消费者,消费组首先在启动时需要订阅需要消费的Topic。
- 一个Topic可以被多个消费组订阅,同样一个消费组也可以订阅多个主题。
队列(Queue):
一个Topic可以有很多队列,消息都存在Queue上,默认是一个Topic在同一个Broker组中是4个。
- 如果一个Topic现在在2个Broker组中,那么就有可能有8个队列。
由于一个Topic可能会有很多的队列,消息发送到哪个队列上?
RocketMQ提供了两种消息队列的选择算法:
- 轮询算法。
- 最小投递延迟算法。
轮询算法:
- 一个队列一个队列发送消息,这些就能保证消息能够均匀分布在不同的队列下,默认的队列选择算法。
最小投递延迟算法:
- 每次消息投递的时候会统计投递的时间延迟,在选择队列的时候会优先选择投递延迟时间小的队列。
- 这种算法可能会导致消息分布不均匀的问题。
消费模式
集群模式:
同一
Topic
下的一条消息只会被同一消费组中的一个消费者消费。
- 消息被负载均衡到了同一个消费组的多个消费者实例上。
广播消费:
每条消息推送给集群内所有的消费者,保证消息至少被每个消费者消费一次。
- 通常用于刷新内存缓存。
Confirm机制
消息生产者把消息发送给
MQ
,如果接收成功,MQ
会返回一个ACK
消息给生产者。如果消息接收不成功,
MQ
会返回一个Nack
消息给生产者。
重试机制
集群消费下,重试机制的本质是
RocketMQ
的延迟消息功能。
Broker
端会为每个Topic
创建一个重试队列 :
- 队列名称是:
%RETRY% + 消费者组名
。达到重试时间后将消息投递到重试队列中进行消费重试(消费者组会自动订阅重试
Topic
)。最多重试消费 16 次,重试的时间间隔逐渐变长。
- 若达到最大重试次数后消息还没有成功被消费,则消息将被投递至死信队列。
死信队列
死信队列用于处理无法被正常消费的消息。
当一条消息初次消费失败,消息队列会自动进行消息重试。
达到最大重试次数后,若消费依然失败,则表明消费者在正常情况下无法正确地消费该消息。
- 此时,消息队列不会立刻将消息丢弃,而是将其发送到该消费者对应的特殊队列中。
RocketMQ
将这种正常情况下无法被消费的消息称为死信消息,将存储死信消息的特殊队列称为死信队列。
Queue分配算法
一个
Topic
中的Queue
只能由Consumer Group
中的一个Consumer
进行消费。
- 而一个
Consumer
可以同时消费多个Queue
中的消息。那么
Queue
与Consumer
间的配对关系是如何确定的,即Queue
要分配给哪个Consumer
进行消费?常见的有四种策略,分别是:
平均分配策略、环形平均策略、一致性
Hash
策略、同机房策略。这些策略是通过在创建
Consumer
时的构造器传进去的。
平均分配策略(默认):
该算法是根据:
Avg = QueueCount / ConsumerCount
的计算结果进行分配的。如果能够整除,则按顺序将
Avg
个Queue
逐个分配,如果不能整除。
- 则将多余出的
Queue
按照Consumer
顺序逐个分配。
环形分配策略:
环形平均算法是指,根据消费者的顺序,依次由
Queue
队列组成的环形图逐个分配,该方法不需要提前计算。
一致性哈希分配策略:
该算法会将
Consumer
的Hash
值作为Node
节点存放到Hash
环上,然后将Queue
的Hash
值也放到Hash
环上。通过顺时针方向,距离
Queue
最近的那个Consumer
就是该Queue
要分配的Consumer
。一致性哈希算法可以有效减少由于消费者组扩容或缩容所带来的大量的
Rebalance
。
- 所以它适合用在
Consumer
数量变化较频繁的场景。但是一致性哈希算法也存在不足,就是分配效率较低,容易导致分配不均的情况。
即每个消费者消费的队列数,有可能相差很大,这样就会造成个别消费者压力过大。
- 可以引入虚拟桶,让
Queue
在Hash
环中尽可能分配均匀。
机房分配策略:
该算法会根据
Queue
的部署机房位置和Consumer
的位置,过滤出当前Consumer
相同机房的Queue
。然后按照平均分配策略或环形平均策略对同机房
Queue
进行分配。如果没有同机房
Queue
,则按照平均配策略或环形平均策略对所有Queue
进行分配。
消息过滤
RocketMQ
的消费者可以根据Tag
进行消息过滤,也支持自定义属性过滤。消息过滤目前是在
Broker
端实现的:
优点是减少了对于
Consumer
无用消息的网络传输。缺点是增加了
Broker
的负担、而且实现相对复杂。
RocketMQ
支持两种方式的消息过滤:
- 一种是
Tag
过滤,另外一种是SQL
过滤。