RocketMq 消息重试机制、死信队列

消息队列中的消息消费时并不能保证总是成功的,那失败的消息该怎么进行消息补偿呢?这就用到今天的主角消息重试和死信队列了 。
生产者消息重试有时因为网路等原因生产者也可能发送消息失败,也会进行消息重试,生产者消息重试比较简单,在springboot中只要在配置文件中配置一下就可以了 。
# 异步消息发送失败重试次数,默认为2rocketmq.producer.retry-times-when-send-async-failed=2# 消息发送失败重试次数,默认为2rocketmq.producer.retry-times-when-send-failed=2也可以通过下面这种方式配置
DefaultMQProducer defaultMQProducer = new DefaultMQProducer();defaultMQProducer.setRetryTimesWhenSendFailed(2);defaultMQProducer.setRetryTimesWhenSendAsyncFailed(2);消费者消息重试Apache RocketMQ 有两种消费模式:集群消费模式和广播消费模式 。消息重试只针对集群消费模式生效;广播消费模式不提供失败重试特性,即消费失败后,失败消息不再重试,继续消费新的消息 。
同时RocketMq Push消费提供了两种消费方式:并发消费和顺序消费 。
并发消费在并发消费中,可能会有多个线程同时消费一个队列的消息,因此即使发送端通过发送顺序消息保证消息在同一个队列中按照FIFO的顺序,也无法保证消息实际被顺序消费,所有并发消费也可以称之为无序消费 。
顺序消费顺序消费是消息生产者发送过来的消息会遵循FIFO队列的思想,先进先出有顺序的消费消息 。对于顺序消息,当消费者消费消息失败后,消息队列 RocketMQ 会自动不断进行消息重试(每次间隔时间为 1 秒),这时,应用会出现消息消费被阻塞的情况 。因此,在使用顺序消息时,务必保证应用能够及时监控并处理消费失败的情况,避免阻塞现象的发生 。
并发消费和顺序消费区别顺序消费和并发消费的重试机制并不相同,顺序消费消费失败后会先在客户端本地重试直到最大重试次数,这样可以避免消费失败的消息被跳过,消费下一条消息而打乱顺序消费的顺序,而并发消费消费失败后会将消费失败的消息重新投递回服务端,再等待服务端重新投递回来,在这期间会正常消费队列后面的消息 。

并发消费失败后并不是投递回原Topic,而是投递到一个特殊Topic,其命名为%RETRY%ConsumerGroupName,集群模式下并发消费每一个ConsumerGroup会对应一个特殊Topic,并会订阅该Topic 。
两者参数差别如下
消费类型
【RocketMq 消息重试机制、死信队列】重试间隔
最大重试次数
顺序消费
间隔时间可通过自定义设置,
SuspendCurrentQueueTimeMillis
最大重试次数可通过自定义参数MaxReconsumeTimes取值进行配置 。该参数取值无最大限制 。若未设置参数值,默认最大重试次数为Integer.MAX
并发消费
间隔时间根据重试次数阶梯变化,取值范围:1秒~2小时 。不支持自定义配置
最大重试次数可通过自定义参数MaxReconsumeTimes取值进行配置 。默认值为16次,该参数取值无最大限制,建议使用默认值
并发消费重试间隔如下:
第几次重试
与上次重试的间隔时间
第几次重试
与上次重试的间隔时间
1
10s
9
7min
2
30s
10
8min
3
1min
11
9min
4
2min
12
10min
5
3min
13
20min
6
4min
14
30min
7
5min
15
1h
8
6min
16
2h
死信队列当一条消息初次消费失败,RocketMQ会自动进行消息重试,达到最大重试次数后,若消费依然失败,则表明消费者在正常情况下无法正确地消费该消息 。此时,该消息不会立刻被丢弃,而是将其发送到该消费者对应的特殊队列中,这类消息称为死信消息(Dead-Letter Message),存储死信消息的特殊队列称为死信队列(Dead-Letter Queue),死信队列是死信Topic下分区数唯一的单独队列 。如果产生了死信消息,那对应的ConsumerGroup的死信Topic名称为%DLQ%ConsumerGroupName,死信队列的消息将不会再被消费 。可以利用RocketMQ Admin工具或者RocketMQ Dashboard上查询到对应死信消息的信息 。
实践出真知Talk is cheap,show you the code.
公共部分创建1.配置文件
rocketmq.name-server=localhost:9876# 消费者组rocketmq.producer.group=producer_grouprocketmq.consumer.topic=consumer_topicrocketmq.consumer.group=consumer_group


推荐阅读