RabbitMQ 常用模式:本地重试与死信队列
RabbitMQ 常用模式本地重试与死信队列推荐方案AUTO 确认 Spring 本地有限重试 RejectAndDontRequeueRecoverer RabbitMQ DLX。方案概览本方案适合秒级、少次数、可幂等的消费失败重试。各组件职责如下组件职责Spring Listener Retry在当前消费者线程内执行有限次数的本地重试RejectAndDontRequeueRecoverer重试耗尽后拒绝消息并设置requeuefalseRabbitMQ DLX将被拒绝的消息路由到死信交换机DLQ保存最终处理失败的消息供告警、排查或人工重放[!NOTE]Spring AMQP 的acknowledge-mode: auto表示由监听容器根据方法是否正常返回来发送 ACK/NACK不等同于 RabbitMQ 的autoAcktrue后者在 Spring AMQP 中对应AcknowledgeMode.NONE。执行链路如下监听方法抛异常 ↓ Spring 在当前消费线程内重试 ↓ 超过最大次数 ↓ RejectAndDontRequeueRecoverer ↓ requeuefalse RabbitMQ 将消息投递到 DLX ↓ DLQ 保存失败消息1. 配置消费者重试Spring Boot 4.x 使用max-retriesspring:rabbitmq:listener:simple:acknowledge-mode:autoprefetch:20concurrency:3max-concurrency:10default-requeue-rejected:falseretry:enabled:truemax-retries:3initial-interval:1smultiplier:2max-interval:10s这个例子的执行过程大致是首次消费失败 ↓ 等待1秒 第1次重试失败 ↓ 等待2秒 第2次重试失败 ↓ 等待4秒 第3次重试失败 ↓ 进入恢复逻辑最终投递 DLQ如果是 Spring Boot 2.x/3.x通常使用旧属性retry:enabled:truemax-attempts:4initial-interval:1smultiplier:2max-interval:10smax-attempts: 4包含第一次执行也就是“首次执行 3 次重试”。当前 Spring Boot 配置已经使用max-retries。参见 Spring Boot RabbitMQ 配置。注意不要配置错位置# 消费者监听重试 spring.rabbitmq.listener.simple.retry # 生产者发送重试 spring.rabbitmq.template.retry2. 声明主队列、DLX 和 DLQimportorg.springframework.amqp.core.Binding;importorg.springframework.amqp.core.BindingBuilder;importorg.springframework.amqp.core.DirectExchange;importorg.springframework.amqp.core.Queue;importorg.springframework.amqp.core.QueueBuilder;importorg.springframework.amqp.rabbit.retry.MessageRecoverer;importorg.springframework.amqp.rabbit.retry.RejectAndDontRequeueRecoverer;importorg.springframework.beans.factory.annotation.Qualifier;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;/** * 功能: * p * 声明订单消息的主队列和死信拓扑。业务消息正常进入主队列 * 消费重试耗尽后消息被拒绝且不重新入队再由RabbitMQ转发到死信队列。 * /p * p * 该配置只负责消息基础设施不处理订单业务逻辑。 * /p */Configuration(proxyBeanMethodsfalse)publicclassOrderRabbitTopologyConfig{publicstaticfinalStringORDER_EXCHANGEorder.exchange;publicstaticfinalStringORDER_ROUTING_KEYorder.created;publicstaticfinalStringORDER_QUEUEorder.created.queue;publicstaticfinalStringORDER_DEAD_EXCHANGEorder.dead.exchange;publicstaticfinalStringORDER_DEAD_ROUTING_KEYorder.created.dead;publicstaticfinalStringORDER_DEAD_QUEUEorder.created.dlq;BeanDirectExchangeorderExchange(){returnnewDirectExchange(ORDER_EXCHANGE,true,false);}BeanQueueorderQueue(){returnQueueBuilder.durable(ORDER_QUEUE).deadLetterExchange(ORDER_DEAD_EXCHANGE).deadLetterRoutingKey(ORDER_DEAD_ROUTING_KEY).build();}BeanBindingorderBinding(Qualifier(orderQueue)Queuequeue,Qualifier(orderExchange)DirectExchangeexchange){returnBindingBuilder.bind(queue).to(exchange).with(ORDER_ROUTING_KEY);}BeanDirectExchangeorderDeadExchange(){returnnewDirectExchange(ORDER_DEAD_EXCHANGE,true,false);}BeanQueueorderDeadQueue(){returnQueueBuilder.durable(ORDER_DEAD_QUEUE).build();}BeanBindingorderDeadBinding(Qualifier(orderDeadQueue)Queuequeue,Qualifier(orderDeadExchange)DirectExchangeexchange){returnBindingBuilder.bind(queue).to(exchange).with(ORDER_DEAD_ROUTING_KEY);}/** * 功能: * p * 当监听器的有限重试全部失败后要求容器拒绝消息且不重新进入原队列。 * 源队列配置DLX后RabbitMQ会将该消息转发到订单死信队列。 * /p * * return 消费重试耗尽后的恢复策略 */BeanMessageRecovererorderMessageRecoverer(){returnnewRejectAndDontRequeueRecoverer(订单消息重试耗尽转入死信队列);}}Spring Boot 在开启监听器重试后默认也会使用RejectAndDontRequeueRecoverer这里显式声明是为了让失败语义更清楚。重试耗尽后消息会被拒绝配置了 DLX 就进入死信队列否则会被丢弃。参见 Spring Boot AMQP 文档。3. 编写消费者importorg.springframework.amqp.rabbit.annotation.RabbitListener;importorg.springframework.stereotype.Component;/** * 功能: * p * 消费订单创建消息并把具体业务处理交给订单消息服务。 * 监听方法正常返回时由Spring自动ACK处理失败时必须继续抛出异常 * 由监听器重试和死信机制统一处理。 * /p */ComponentpublicclassOrderCreatedMessageListener{privatefinalOrderMessageServiceorderMessageService;publicOrderCreatedMessageListener(OrderMessageServiceorderMessageService){this.orderMessageServiceorderMessageService;}/** * 功能: * p * 消费订单创建事件。业务服务执行完成后方法正常返回Spring发送ACK * 业务服务抛出异常时本方法不捕获交给Spring执行有限重试。 * /p * * param message 订单创建消息messageId用于消费幂等 */RabbitListener(queuesOrderRabbitTopologyConfig.ORDER_QUEUE)publicvoidconsume(OrderCreatedMessagemessage){orderMessageService.consume(message);}}这里最重要的是不要捕获异常后只打印日志。错误写法RabbitListener(queuesorder.created.queue)publicvoidconsume(OrderCreatedMessagemessage){try{orderMessageService.consume(message);}catch(Exceptionexception){log.error(订单消息处理失败,exception);}}异常被吞掉后监听方法正常返回Spring 认为处理成功 ↓ 发送 ACK ↓ 不会重试也不会进入 DLQ如果确实需要记录日志必须继续抛出RabbitListener(queuesorder.created.queue)publicvoidconsume(OrderCreatedMessagemessage){try{orderMessageService.consume(message);}catch(Exceptionexception){log.error(订单消息处理失败messageId{},message.getMessageId(),exception);throwexception;}}4. 业务服务必须实现幂等importorg.springframework.stereotype.Service;importorg.springframework.transaction.annotation.Transactional;/** * 功能: * p * 在数据库事务内完成订单消息幂等校验和业务处理。 * 消息重试或ACK丢失时可能发生重复投递因此通过messageId唯一记录 * 确保相同消息不会重复修改订单。 * /p */ServicepublicclassOrderMessageService{privatefinalConsumeLogRepositoryconsumeLogRepository;privatefinalOrderRepositoryorderRepository;publicOrderMessageService(ConsumeLogRepositoryconsumeLogRepository,OrderRepositoryorderRepository){this.consumeLogRepositoryconsumeLogRepository;this.orderRepositoryorderRepository;}/** * 功能: * p * 消费订单事件。首次消费时写入幂等记录并更新订单 * 重复消息直接返回使监听器可以安全ACK。 * /p * * param message 待处理的订单创建消息 */Transactional(rollbackForException.class)publicvoidconsume(OrderCreatedMessagemessage){booleanisFirstConsumptionconsumeLogRepository.tryInsert(message.getMessageId());if(!isFirstConsumption){return;}orderRepository.createOrder(message.getOrderId(),message.getUserId());}}message_id必须有数据库唯一索引CREATEUNIQUEINDEXuk_mq_consume_log_message_idONmq_consume_log(message_id);5. 消息什么时候进入 DLQ配置成功后监听器正常返回 → Spring ACK → 消息删除 监听器抛异常但重试成功 → Spring ACK → 消息删除 监听器一直失败 → 重试耗尽 → basic.reject / basic.nackrequeuefalse → order.dead.exchange → order.created.dlqRabbitMQ 会在死信消息的 Header 中增加x-death记录原队列、死信原因和次数。参见 RabbitMQ DLX 文档。注意这里的 Spring 重试是消费者进程内重试重试期间消息保持 Unacked重试会占用消费者线程每次本地重试不会增加x-death只有最终被 RabbitMQ 死信转发时才产生x-death记录。所以这种方案适合秒级、次数较少的重试。分钟级、小时级重试应改成主队列 ↓ 失败 短延时重试队列 ↓ 再失败 长延时重试队列 ↓ 超过上限 最终 DLQ6. 一个容易遇到的部署问题如果order.created.queue已经存在并且以前没有配置 DLX再用上面的代码声明可能报PRECONDITION_FAILED - inequivalent arg x-dead-letter-exchange因为 RabbitMQ 不允许直接修改已有队列的声明参数。处理方式测试环境删除旧队列后重新声明生产环境优先通过 RabbitMQ Policy 设置 DLX不要直接删除仍有消息的生产队列。RabbitMQ 官方也更推荐使用 Policy 配置 DLX因为 Policy 可以动态调整而硬编码的x-arguments通常需要重新创建队列。参见 RabbitMQ DLX Policy。7. 验收测试至少验证以下场景/** * 业务处理成功时验证监听器只执行一次且消息不会进入DLQ。 */TestvoidshouldAcknowledgeMessageWhenBusinessSucceeds(){}/** * 业务持续失败时验证达到重试上限后消息进入订单DLQ。 */TestvoidshouldMoveMessageToDeadQueueAfterRetriesExhausted(){}/** * 同一个messageId被重复投递时验证订单只创建一次。 */TestvoidshouldKeepBusinessIdempotentWhenMessageIsRedelivered(){}集成测试可以从 DLQ 读取结果MessagedeadMessagerabbitTemplate.receive(OrderRabbitTopologyConfig.ORDER_DEAD_QUEUE,15_000);assertThat(deadMessage).isNotNull();assertThat(deadMessage.getMessageProperties().getHeaders()).containsKey(x-death);8. 运维与重放建议为 DLQ 的消息数量、最老消息滞留时间和持续增长趋势配置监控告警。重放前先定位失败原因并修复消费者避免消息重新进入“主队列 → 重试 → DLQ”的循环。重放工具应保留原始messageId继续复用消费端幂等校验同时记录操作人、重放时间、批次和结果。DLQ 是失败消息的隔离区不等同于自动补偿机制是否自动重放应根据异常类型、业务风险和重试间隔单独设计。参考资料Spring Boot RabbitMQ 配置属性Spring Boot AMQP 文档Spring AMQP 监听容器配置RabbitMQ Dead Letter ExchangesRabbitMQ Reliability Guide

相关新闻

本特利3500软件组态实操指南:从硬件连接到报警逻辑配置

本特利3500软件组态实操指南:从硬件连接到报警逻辑配置

1. 项目概述:从“黑盒子”到透明监控在工业自动化领域,尤其是大型旋转机械(如汽轮机、压缩机、发电机)的监测保护系统中,本特利内华达的3500系列框架式监测系统堪称是“定海神针”。它负责采集振动、位移、转速等关键参…

2026/7/31 4:54:29 阅读更多 →
蓝牙产品BQB与FCC认证实战指南:从原理到拿证全流程解析

蓝牙产品BQB与FCC认证实战指南:从原理到拿证全流程解析

1. 项目概述:为什么你的蓝牙产品必须“持证上岗”?做硬件产品,尤其是带无线功能的,最绕不开的就是各种认证。最近在折腾一个带蓝牙功能的小玩意儿,从打样到功能调试都挺顺利,结果临到要量产了,被…

2026/7/31 4:54:29 阅读更多 →
STM32 PWM呼吸灯实现:从原理到电机控制的全解析

STM32 PWM呼吸灯实现:从原理到电机控制的全解析

1. 从“亮与灭”到“明与暗”:PWM呼吸灯的核心逻辑如果你玩过单片机,点亮一个LED灯通常是第一个“Hello World”程序。但很快你就会觉得,让灯一直亮着或一直灭掉,实在太单调了。于是,“呼吸灯”就成了点亮技能树后的第…

2026/7/31 4:54:29 阅读更多 →

最新新闻

汽车漆面车漆缺陷数据集 深度学习框架目标检测算法 Yolov8训练道路 建立基于YOLOv8道路汽车漆面缺陷(划痕)检测系统

汽车漆面车漆缺陷数据集 深度学习框架目标检测算法 Yolov8训练道路 建立基于YOLOv8道路汽车漆面缺陷(划痕)检测系统

基于YOLOv8道路汽车漆面缺陷(划痕)检测系统 文章目录基于YOLOv8道路汽车漆面缺陷(划痕)检测系统1. 安装依赖2. 数据集准备与划分3. 数据预处理4. 配置YOLOv85. 训练和评估模型6. 推理与可视化7. 构建GUI应用程序道路汽车漆面车漆缺…

2026/7/31 5:30:44 阅读更多 →
基于CH552的USB CDC设备开发:从协议解析到工程实践

基于CH552的USB CDC设备开发:从协议解析到工程实践

1. 项目概述:从串口到USB的认知跃迁上次我们聊了CH552开发环境的搭建和点灯,算是和这位“老朋友”打了个招呼。这次,咱们得动点真格的了,主题是USB。对于很多从51、STM32转过来的朋友,一提到USB,心里可能就…

2026/7/31 5:30:44 阅读更多 →
C++ QT登录界面实战:从架构设计到安全实现的完整指南

C++ QT登录界面实战:从架构设计到安全实现的完整指南

1. 项目概述与核心价值最近在带几个新人做项目,发现他们虽然C语法和QT框架的基本控件都懂,但一到要独立设计一个完整的、能投入实际使用的系统登录界面时,就有点无从下手。要么是界面布局混乱,要么是逻辑耦合严重,要么…

2026/7/31 5:30:44 阅读更多 →
图像超分辨率重建系统 并支持SRResNet和SRGAN算法,且使用PyQt5进行界面设计。

图像超分辨率重建系统 并支持SRResNet和SRGAN算法,且使用PyQt5进行界面设计。

python语言中如何构建图像超分辨率重建系统,并支持SRResNet和SRGAN算法,且使用PyQt5进行界面设计。 文章目录 python语言中如何构建图像超分辨率重建系统,并支持SRResNet和SRGAN算法,且使用PyQt5进行界面设计。1. 安装依赖库2. 创…

2026/7/31 5:30:44 阅读更多 →
ESP32固件烧录全攻略:从flash_download_tool配置到深度问题排查

ESP32固件烧录全攻略:从flash_download_tool配置到深度问题排查

1. 从一次失败的固件烧录说起那天下午,我正试图给一块新到的ESP32-C3开发板刷入一个自定义的固件。按照惯例,我打开了乐鑫官方的flash_download_tool,选择了正确的芯片型号,加载了编译好的.bin文件,设置了正确的0x0偏移…

2026/7/31 5:30:44 阅读更多 →
C语言函数指针实现状态机:从原理到嵌入式按键实战

C语言函数指针实现状态机:从原理到嵌入式按键实战

1. 项目概述:为什么我们需要一个“简单易懂”的状态机?在嵌入式开发、协议解析、UI界面管理这些领域里,代码的逻辑流转常常不是一条直线走到底。比如,一个按键的处理,它可能处于“空闲”、“按下消抖”、“长按计时”、…

2026/7/31 5:29:44 阅读更多 →

日新闻

物理复制比逻辑复制好在哪?数据库复制原理详解

物理复制比逻辑复制好在哪?数据库复制原理详解

数据库复制是把主库数据同步到备库的机制,分为逻辑复制和物理复制两种。逻辑复制传输的是 SQL 语句或行变更事件,物理复制传输的是存储引擎底层的物理日志。阿里云 PolarDB(云原生数据库)采用物理复制,在同步延迟、数据…

2026/7/31 0:00:34 阅读更多 →
BilibiliDown:3分钟学会B站视频下载的终极指南

BilibiliDown:3分钟学会B站视频下载的终极指南

BilibiliDown:3分钟学会B站视频下载的终极指南 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader 😳 项目地址: https://gitcode.com/gh_mirrors/bi/Bilib…

2026/7/31 0:00:34 阅读更多 →
有哪些游戏数据AI平台?游戏行业Data+AI融合方案盘点

有哪些游戏数据AI平台?游戏行业Data+AI融合方案盘点

当前,游戏行业的“DataAI融合”已从概念验证进入价值落地阶段。根据IDC 2025年数据,中国AI游戏云市场规模已达18.6亿元;同时,游戏研发环节AI渗透率高达86%,生成式AI内容普及率超过50%。面对庞大的市场,游戏…

2026/7/31 0:00:34 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/31 1:03:03 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/29 14:34:28 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/31 4:19:39 阅读更多 →

月新闻