跟我学RocketMQ之聊聊死信队列
有段时间没写东西了,再不写就有点说不过去了。
今天我们讨论一个轻松的话题,来聊聊RocketMQ中的死信队列
是什么是死信队列
在之前的文章中,我们聊过RocketMQ的消息重试机制。
如果消息消费失败,消费者返回Reconsume_later给RocketMQ broker,队列会按照重试时间窗口对消息进行重试。
当达到最大重试次数(默认16次),消息还是消费失败,RocketMQ不会将该消息丢弃而是会把它保存到私信队列中。
这种不能被消费者正常处理的消息我们一般称之为 死信消息(Dead-Letter Message),将存储死信消息的队列称之为 死信队列(Dead-Letter Queue,DLQ)
死信消息/队列特点
首先看下死信消息具备的特点:
- 私信队列中的消息不会再被消费者正常消费,也就是一般情况下DLQ是消费者不可见的
- 死信存储有效期与正常消息相同,均为 3 天,3 天后会被自动删除。因此,我们要保证在死信消息产生后的 3 天内对其进行及时处理
而死信队列则具有以下特性:
- 每个死信队列对应一个 Group ID,也就是每个消费者组都有一个私信队列; 而不是对应单个消费者实例
- 如果一个 Group ID 未产生死信消息,消息队列 RocketMQ 不会为其创建相应的死信队列
- 一个死信队列包含了对应 Group ID 下产生的所有死信消息,不论该消息属于哪个 Topic,也就是对于某个消费者组,它的所有的死信共享一个死信队列
使用console查看死信消息
我们可以通过console应用直观的查看死信队列中的消息。关于如何搭建console,请移步 安装RocketMQ-Console管理平台
- 在cnosole中查询出现死信队列的主题
- 在消息界面根据主题查询死信消息
如何处理死信
了解了什么是死信,以及如何在console中查看死信。接下来我们看一下开发最关心的问题,如何处理死信?
实际上,当一条消息进入死信队列,就意味着某些因素导致消费者无法正常消费该消息(比如,代码中存在bug/数据库宕机等)。
因此,对于死信消息,通常需要开发进行特殊处理。
最关键的步骤是要排查可疑因素并解决代码中存在的bug。然后我们通过:
控制台重新发送该消息,让消费者对该消息重新消费一次。
除了通过console手动推送消息进行消费,我们也可以查询死信中消息,将消息重新投递到原topic进行重新消费。
死信Topic的命名为:%DLQ% + Consumer组名,如:%DLQ%online-tst。
举个例子,我们想要重新消费 %DLQ%online-tst 中的一条死信消息,就可以先通过mqadmin命令查询到该消息,然后将消息重新投递到原topic中,等待业务逻辑进行消费处理即可。前提是消费过程中要保证消费幂等。关于消费幂等,请移步 跟我学RocketMQ之消息幂等
附录:mqadmin死信相关指令
常见的mqadmin操作死信队列的命令如下:
操作 | 命令样例 |
---|---|
更改死信队列权限 | 将死信队列只写权限更改为读写权限: bin/mqadmin updateTopicPerm -c ClusterB -t %DLQ%online-tst -p 6 -n 192.168.1.x:9876 |
查询死信队列状态 | bin/mqadmin topicStatus -n 192.168.1.x:9876 -t %DLQ%online-tst |
根据offset查询消息内容 | bin/mqadmin queryMsgByOffset -n localhost:9876 -t %DLQ%online-tst -b broker-a -i 0 -o 108 |
版权声明:
原创不易,洗文可耻。除非注明,本博文章均为原创,转载请以链接形式标明本文地址。