前言
在RocketMQ中,死信消息(Dead-Letter Message)是指那些在正常情况下无法被消费者消费的消息。这些消息会被存储在死信队列(Dead-Letter Queue,简称DLQ)中。
死信消息的特性包括:
- 不会再被消费者正常消费:一旦消息被标记为死信消息,它们将不会被正常的消费者消费。
- 有效期与正常消息相同,均为3天:死信消息的有效期与正常消息相同,均为3天。这意味着在死信消息产生后的3天内,如果消费者没有处理该消息,它将被自动删除。
- 死信队列特性:一个死信队列对应一个Group ID,而不是对应单个消费者实例。如果一个Group ID未产生死信消息,RocketMQ不会为其创建相应的死信队列。一个死信队列包含对应Group ID产生的所有死信消息,不论该消息属于哪个Topic。
使用死信队列可以帮助消费者在处理消息失败时,将失败的消息重新发送到指定的队列,以便进行进一步的处理或分析。
死信消息
死信消息就是指如果消息最终无法被正常消费,那么这条消息就会成为死信消息
RocketMQ中,消息会变成死信消息有两种情况
第一种就是消息重试次数已经达到了最大重试次数
最大重试次数取决于并发消费还是顺序消费
-
顺序消费,默认最大重试次数就是
Integer.MAX_VALUE
,基本上就是无限次重试,所以默认情况下顺序消费的消息几乎不可能成为死信消息 -
并发消费的话,那么最大重试次数默认就是16次
当然可以通过如下的方法来设置最大重试次数
DefaultMQPushConsumer#setMaxReconsumeTimes
除了上面的情况之外,当在并发消费模式下,你可以在消息消费失败之后手动指定,直接让消息变成死信消息
在并发消费消息的模式下,处理消息的方法有这么一个参数
ConsumeConcurrentlyContext
这个类中有这么一个属性
这个参数值有三种情况,注释也有写:
-
小于0,那么直接会把消息放到死信队列,成为死信消息。注释写的是=-1,其实只要小于0就可以成为死信消息,不一定非得是-1
-
0,默认就是0,这个代表消息重试消费,并且重试的时间间隔(也就是延迟级别)由服务端决定,也即是前面重试消息提到的
delayLevel = 3 + 已经重试次数
-
大于0,此时就表示客户端指定消息重试的时间间隔,是几就代表延迟级别为几,比如设置成1,那么延迟级别就为1
所以,在并发消费模式下,可以通过设置这个参数值为-1,直接让处理失败的消息成为死信消息
当消息成为死信消息之后,消息并不会丢失
RocketMQ会将死信消息保存在死信Topic底下,Topic格式为
%DLQ% + 消费者组名称
跟重试Topic的格式有点像,只是将%RETRY%
换成了%DLQ%
如果你想知道有哪些死信消息,只需要订阅这个Topic即可获得
总结
所以总的来说,两种情况会让消息成为死信消息:
-
消息重试次数超过最大次数,跟消息的处理方式有关,默认情况下顺序处理最大次数是几乎是无限次,也就是几乎不可能成为死信消息;并发处理的情况下,最大重试次数默认就是16次。最大重试次数是可以设置的。
-
在并发处理的情况下,通过
ConsumeConcurrentlyContext
将delayLevelWhenNextConsume
属性设置成-1,让消息直接变成死信消息
当消息成为死信消息的时候,会被存到%DLQ% + 消费者组名称
这个Topic下
用户可以通过这个Topic获取到死信消息,手动干预处理这些消息
联系方式
关于文章中大家有任何疑问可以通过关注公众号《编程乐学》进行留言,同时,公众号还有更多有趣的项目以及关于学习编程的笔记资料大家可以看看,欢迎大家进行留言。