在分布式系统中,为了保证消息的可靠传输,RocketMQ 提供了自动重试机制:当消费者消费失败时,RocketMQ 会在一段时间后重试投递该消息。若在超过一定次数(默认 16 次)后仍然消费失败,消息将被放入死信队列(Dead Letter Queue,DLQ)。使用 Spring Cloud Alibaba RocketMQ 时,也同样会遵循这一原则。本文将介绍 RocketMQ 死信队列的原理、在 Spring Cloud Alibaba 中如何配置重试次数,以及如何查看和处理死信消息。
一、RocketMQ 死信队列概述
-
触发条件
- 当消费者多次(默认为 16 次)消费某条消息都返回
RECONSUME_LATER
或抛出异常,Broker 便会将该消息放入死信队列中,以防止这条消息一直阻塞在重试队列里。
- 当消费者多次(默认为 16 次)消费某条消息都返回
-
队列命名
- 死信队列的 Topic 命名约定为:
%DLQ%{ConsumerGroup}
。 - 例如,消费者组名为
myConsumerGroup
,则该组对应的死信队列 Topic 就是"%DLQ%myConsumerGroup"
。
- 死信队列的 Topic 命名约定为:
-
特性
- 进入死信队列的消息不会被再次自动投递,需要运维或开发者手动处理(例如在控制台查看并人工干预,或编写代码对
%DLQ%myConsumerGroup
进行消费、补偿等)。
- 进入死信队列的消息不会被再次自动投递,需要运维或开发者手动处理(例如在控制台查看并人工干预,或编写代码对
-
常见处理方式
- 补偿:手动拉取死信消息,分析原因并尝试修复,再将消息重新投递或写到新 Topic 进行二次消费。
- 记录/报警:如果死信消息大规模累积,需要及时告警,并排查是否出现了业务逻辑缺陷或消费端故障。
二、在 Spring Cloud Alibaba RocketMQ 中的配置
1. 基于 Spring Cloud Stream RocketMQ 的使用
在 Spring Cloud Alibaba 场景下,RocketMQ 既可通过 Spring Cloud Stream 进行整合,也可直接使用原生 RocketMQTemplate
或 DefaultMQPushConsumer
的方式。下面先以 Spring Cloud Stream 为例说明如何配置重试次数。
(1)添加依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rocketmq</artifactId>
<!-- 版本号根据实际使用的 Spring Cloud Alibaba 版本选择 -->
<version>2.2.10.RELEASE</version>
</dependency>
(2)配置文件示例
spring:
cloud