RocketMQ 死信队列(DLQ)实战:原理 + 开发 + 运维 + 架构应用指南

news2025/6/2 9:31:12

🚀RocketMQ 死信队列(DLQ)实战:原理 + 开发 + 运维 + 架构应用指南


第一章:什么是死信队列(DLQ)?

1.1 死信队列定义

在 RocketMQ 中,死信队列(Dead Letter Queue,简称 DLQ)用于存储那些消费失败达到最大重试次数的消息。一般情况下,一条消息如果消费失败,RocketMQ 会自动进行多次重试(默认 16 次),如果仍然失败,就会将消息丢入死信队列,避免影响正常消息的消费。

1.2 死信队列的命名规则

RocketMQ 自动为每个消费者组创建死信队列,命名规则:

%DLQ%{consumerGroup}

例如,如果你的消费组是 order-consumer-group,那么死信队列的 Topic 名称就是:

%DLQ%order-consumer-group

⚠️ 注意:死信队列的消息是不会被原消费者再次消费的,必须新建 Consumer Group 订阅 %DLQ%consumerGroup 才能消费。

1.3 为什么需要死信队列?

  • 防止阻塞正常消费
    如果没有死信机制,坏消息会反复重试,导致消费堆积,影响系统整体性能。
  • 数据可追溯
    死信消息是异常数据的沉淀,可以用于后续排查问题、数据修正、补偿处理。
  • 系统容错增强
    通过死信队列可以做到业务异常的自动隔离,保护系统整体稳定性。

1.4 工作流程图

生产者 --> 正常 Topic --> 消费者
                      |
                      | 消费失败
                      V
                自动重试 N 次
                      |
                      | 超过最大重试次数
                      V
               --> 死信队列(DLQ)

第二章:DLQ 实战开发

2.1 工程搭建

2.1.1 Maven 依赖

pom.xml 中引入 RocketMQ 相关依赖:

<dependency>
    <groupId>org.apache.rocketmq</groupId>
    <artifactId>rocketmq-spring-boot-starter</artifactId>
    <version>2.3.1</version>
</dependency>

2.1.2 配置文件 application.yml

spring:
  rocketmq:
    name-server: 127.0.0.1:9876
    producer:
      group: normal-producer-group
    consumer:
      group: normal-consumer-group

2.2 模拟消费失败进入死信队列

2.2.1 生产者发送消息

package com.example.rocketmq.producer;

import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MessageProducer {

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    public void sendMessage(String topic, String message) {
        rocketMQTemplate.convertAndSend(topic, message);
    }
}

2.2.2 消费者模拟异常消费

package com.example.rocketmq.consumer;

import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Service;

/**
 * 正常消费者,故意抛异常,触发重试
 */
@Service
@RocketMQMessageListener(topic = "test-topic", consumerGroup = "normal-consumer-group")
public class FailMessageConsumer implements RocketMQListener<String> {

    @Override
    public void onMessage(String message) {
        System.out.println("收到消息: " + message);
        // 故意制造异常,触发重试
        throw new RuntimeException("模拟消费失败,触发重试!");
    }
}

2.2.3 触发逻辑

RocketMQ 默认重试 16 次,重试完就进入死信队列 %DLQ%normal-consumer-group


2.3 死信队列消费者

我们需要新建一个 Consumer Group 来监听死信队列。

package com.example.rocketmq.consumer;

import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Service;

/**
 * 死信队列监听消费者
 */
@Service
@RocketMQMessageListener(topic = "%DLQ%normal-consumer-group", consumerGroup = "dlq-consumer-group")
public class DeadLetterQueueConsumer implements RocketMQListener<String> {

    @Override
    public void onMessage(String message) {
        System.out.println("【死信队列】收到消息:" + message);
        // 在这里进行补偿逻辑,比如修复数据后重新发送
    }
}

⚠️ 必须使用新的 Consumer Group!不能和原来的 normal-consumer-group 一样。


第三章:CLI 运维排查死信队列

3.1 查看死信消息数量

./mqadmin topicStatus -n 127.0.0.1:9876 -t %DLQ%normal-consumer-group

输出示例:

#Topic: %DLQ%normal-consumer-group
#QueueId: 0
OffsetMax: 10
OffsetMin: 0
LastUpdateTimestamp: 1690000000000

OffsetMax - OffsetMin 就是当前死信消息的总数。


3.2 查询死信消息内容

根据关键字查询:

./mqadmin queryMsgByKey -n 127.0.0.1:9876 -t %DLQ%normal-consumer-group -k your-key

或者根据 MessageId 查询:

./mqadmin queryMsgById -n 127.0.0.1:9876 -i your-message-id

第四章:死信监控与告警实战

推荐使用 RocketMQ Exporter + Prometheus + Grafana:

  • RocketMQ Exporter:采集 RocketMQ 各种 Topic 的堆积、TPS 等指标。
  • Prometheus:存储和管理监控数据。
  • Grafana:可视化仪表盘。

重点监控指标:

  • 死信队列 Topic 的消息堆积数。
  • Consumer 消费 TPS。
  • Broker 存活状态。
  • NameServer 存活状态。

监控示例图

(这里可以配一张死信队列监控的 Grafana Dashboard)


第五章:死信队列典型应用场景

场景描述
电商订单支付通知回调失败,消息进入 DLQ,人工补偿
物流轨迹推送失败消息网络波动,异常轨迹推送流入 DLQ
金融交易通知失败核心交易失败,DLQ 隔离异常,防止系统连锁崩溃
大数据 ETL 处理失败处理异常数据集中流入 DLQ,后续修正
直播秒杀高并发流控消费失败数据进入 DLQ,防止系统过载

第六章:面试必考问题总结

面试题标准回答框架
什么是死信队列?消费失败超过最大重试次数的消息存储队列。
死信队列的 Topic 名称?%DLQ%{consumerGroup}
如何消费死信消息?使用新的 Consumer Group 监听 DLQ Topic。
死信队列的应用场景有哪些?异常数据隔离,人工补偿,避免阻塞正常消费。
死信消息能否重新消费?可以,消费后补偿处理,重新发送到原 Topic。

第七章:全栈工程师视角:为什么每个微服务系统都必须有死信处理机制?

  • 分布式系统中,异常一定会发生,消息队列不能期望 100% 无故障消费。
  • 没有死信队列:坏消息反复重试,阻塞正常消费,最终系统不可用。
  • 有死信队列:坏消息隔离,正常消息畅通,系统更稳定。
  • 补偿机制:死信消息修正后重新投递,减少业务损失。
  • 监控报警:死信数量异常增长,快速触发报警,及时发现系统隐患。

第八章:大厂死信队列实践案例总结

在大型互联网公司中,死信队列(DLQ)不仅仅是异常消息隔离的工具,而是整个微服务稳定性保障体系的重要一环。下面来看几个真实的大厂案例。


8.1 京东:秒杀订单处理

背景

京东的秒杀活动中,瞬时高并发导致订单系统巨大的写入压力,偶发的消费失败不可避免。

做法

  • 每个秒杀订单创建失败、库存扣减失败的消息,重试达到上限后,进入死信队列。
  • 死信队列由后台订单补偿平台统一管理
  • 补偿平台提供:
    • 死信消息查询
    • 人工审核/修复数据
    • 重发到正常 Topic 再次处理

特点

  • 保证正常消息不被阻塞,坏数据独立。
  • 确保秒杀体验的稳定性和一致性
  • 补偿平台数据可追溯,支持订单回溯和修复。

8.2 美团:支付链路通知补偿

背景

美团支付系统需要向商户推送支付成功、退款等通知,但存在商户网络波动、接口异常等不可控问题。

做法

  • 通知发送失败的消息会重试,最终进入死信队列。
  • 死信队列监控 + 告警系统
    • 死信堆积达到阈值,自动触发运维报警。
    • 定期巡检死信消息,归类整理。
  • 统一补偿系统
    • 根据失败原因分流:接口异常、商户拒绝、格式错误。
    • 自动补偿简单失败消息,复杂失败消息需要人工干预。

特点

  • 死信隔离异常通知,提升主链路可靠性。
  • 告警+巡检+自动补偿,高效恢复异常数据。
  • 保护支付系统的 SLA(服务等级协议)指标。

8.3 某大型国有银行:金融交易死信处理

背景

金融核心交易对实时性和一致性要求极高,任何消息丢失或堆积都可能带来巨大风险。

做法

  • 核心交易消息采用 RocketMQ,开启事务消息机制。
  • 消息消费失败,重试后进入死信队列。
  • 定制化死信处理平台
    • 自动拉取死信消息,记录审计日志。
    • 自动分类处理:网络故障重试,数据错误人工处理。
    • 严格权限管控,避免非法操作死信消息。
  • 与合规审计系统对接,死信数据纳入审计范围。

特点

  • 死信消息入库,保证金融交易数据可追溯
  • 自动+人工结合的补偿机制,降低交易风险
  • 合规要求下,审计合规透明

第九章:最佳实践总结

实践建议说明
生产者端保证幂等性消息可能重投,确保幂等防止重复处理。
合理配置最大重试次数根据业务特点配置,比如 3次、5次,防止死循环重试。
定期巡检死信队列每日定时检查 DLQ,发现并处理异常消息。
搭建后台补偿平台支持死信消息查看、修复、重发功能。
建立监控告警机制监控死信堆积量,超阈值报警,及时发现消费异常。
死信消息分类处理简单异常自动补偿,复杂异常人工审核。
与审计系统对接对于金融、电商等重要系统,死信处理过程应全链路可追溯,合规记录。

🎯 全文总结

死信队列不仅是消息中间件的“容错保险”,更是微服务体系稳定性的最后防线。通过合理配置、规范使用死信队列,配合监控和补偿平台,可以极大提升系统健壮性、可用性,助力企业应对高并发、高可靠的业务挑战。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2393506.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android studio 查看aar源码出现/* compiled code */

如图查看aar源码时看不到具体实现&#xff0c;在排除是sdk版本导致的问题后&#xff0c;下面说解决方法 打开设置&#xff0c;找到插件 输入decompiler 搜索 这个是自带的反编译工具&#xff0c;启用就好了

用HTML5+JavaScript实现汉字转拼音工具

用HTML5JavaScript实现汉字转拼音工具 前一篇博文&#xff08;https://blog.csdn.net/cnds123/article/details/148067680&#xff09;提到&#xff0c;当需要将拼音添加到汉字上面时&#xff0c;用python实现比HTML5JavaScript实现繁琐。在这篇博文中用HTML5JavaScript实现汉…

基于Java,SpringBoot,Vue,UniAPP医院预约挂号买药就诊病例微信小程序系统设计

摘要 随着医疗信息化的不断推进以及“互联网医疗”模式的广泛普及&#xff0c;传统医院挂号流程中存在的排队时间长、资源分配不均等问题日益凸显&#xff0c;急需通过数字化手段加以解决。本研究设计并实现了一套基于Java、SpringBoot、Vue与UniAPP技术栈的医院预约挂号微信小…

ONNX模型的动态和静态量化

引言  通常我们将模型转换为onnx格式之后&#xff0c;模型的体积可能比较大&#xff0c;这样在某些场景下就无法适用。最近想在移动端部署语音识别、合成模型&#xff0c;但是目前的效果较好的模型动辄几个G&#xff0c;于是便想着将模型压缩一下。本文探索了两种压缩方法&…

如何用Python抓取Google Scholar

文章目录 [TOC](文章目录) 前言一、为什么要抓取Google Scholar&#xff1f;二、Google Scholar 抓取需要什么三、为什么代理对于稳定的抓取是必要的四、一步一步谷歌学者抓取教程4.1. 分页和循环4.2. 运行脚本 五、完整的Google Scholar抓取代码六、抓取Google Scholar的高级提…

Wireshark对usb设备进行抓包找不到USBPcap接口的解决方案

引言 近日工作需要针对usb设备进行抓包&#xff0c;但按照wireshark安装程序流程一步步走&#xff0c;即使勾选了安装USBPcap安装完成后开启wireshark依然不显示USBPcap接口&#xff0c;随设法进行解决。 最终能够正常显示USBPcap接口并能够正常使用进行抓包 解决方案&#x…

Socket 编程 UDP

目录 1. UDP网络编程 1.1 echo server 1.1.1 接口 1.1.1.1 创建套接字 1.1.1.2 绑定 1.1.1.3 bzero 1.1.1.4 htons&#xff08;主机序列转网络序列&#xff09; 1.1.1.5 inet_addr&#xff08;主机序列IP转网络序列IP&#xff09; 1.1.1.6 recvfrom&#xff08;让服务…

Jenkins实践(8):服务器A通过SSH调用服务器B执行Python自动化脚本

Jenkins实践(8):服务器A通过SSH调用服务器B执行Python自动化脚本 1、需求: 1、Jenkins服务器在74上,Python脚本在196服务器上 2、需要在服务器74的Jenkins上调用196上的脚本执行Python自动化测试 2、操作步骤 第一步:Linux Centos7配置SSH免密登录 Linux Centos7配置S…

lua的注意事项2

总之&#xff0c;下面的返回值不是10&#xff0c;a&#xff0c;b 而且

前端八股之HTML

前端秘籍-HTML篇 1. src和href的区别 src 用于替换当前元素&#xff0c;href 用于在当前文档和引用资源之间确立联系。 &#xff08;1&#xff09;src src 是 source 的缩写&#xff0c;指向外部资源的位置&#xff0c;指向的内容将会嵌入到文档中当前标签所在位置&#xff1…

鲲鹏Arm+麒麟V10,国产化信创 K8s 离线部署保姆级教程

Rainbond V6 国产化部署教程&#xff0c;针对鲲鹏 CPU 麒麟 V10 的离线环境&#xff0c;手把手教你从环境准备到应用上线&#xff0c;所有依赖包提前打包好&#xff0c;步骤写成傻瓜式操作指南。别说技术团队了&#xff0c;照着文档一步步来&#xff0c;让你领导来都能独立完成…

【C++ Qt】认识Qt、Qt 项目搭建流程(图文并茂、通俗易懂)

每日激励&#xff1a;“不设限和自我肯定的心态&#xff1a;I can do all things。 — Stephen Curry” 绪论​&#xff1a; 本章将开启Qt的学习&#xff0c;Qt是一个较为古老但仍然在GUI图形化界面设计中有着举足轻重的地位&#xff0c;因为它适合嵌入式和多种平台而被广泛使用…

IoT/HCIP实验-1/物联网开发平台实验Part2(HCIP-IoT实验手册版)

文章目录 概述产品和设备实例的产品和设备产品和设备的关联单个产品有多个设备为产品创建多个设备产品模型和物模型设备影子&#xff08;远程代理&#xff09; 新建产品模型定义编解码插件开发编解码插件工作原理消息类型与二进制码流添加消息&#xff08;数据上报消息&#xf…

Replacing iptables with eBPF in Kubernetes with Cilium

source: https://archive.fosdem.org/2020/schedule/event/replacing_iptables_with_ebpf/attachments/slides/3622/export/events/attachments/replacing_iptables_with_ebpf/slides/3622/Cilium_FOSDEM_2020.pdf 使用Cilium&#xff0c;结合eBPF、Envoy、Istio和Hubble等技术…

数学建模之最短路径问题

1 问题的提出 这个是我们的所要写的题目&#xff0c;我们要用LINGO编程进行编写这个题目&#xff0c;那么就是需要进行思考这个怎么进行构建这个问题的模型 首先起点&#xff0c;中间点&#xff0c;终点我们要对这个进行设计 2 三个点的设计 起点的设计 起点就是我们进去&am…

测试概念 和 bug

一 敏捷模型 在面对在开发项目时会遇到客户变更需求以及合并新的需求带来的高成本和时间 出现的敏捷模型 敏捷宣言 个人与交互重于过程与工具 强调有效的沟通 可用的软件重于完备的文档 强调轻文档重产出 客户协作重于合同谈判 主动及时了解当下的要求 相应变化…

zynq 级联多个ssd方案设计(ECAM BUG修改)

本文讲解采用zynq7045芯片如何实现200T容量高速存储方案设计&#xff0c;对于大容量高速存储卡&#xff0c;首先会想到采用pcie switch级联方式&#xff0c;因为单张ssd的容量是有限制的&#xff08;目前常见的m.2接口容量为4TB&#xff0c;U.2接口容量为16TB&#xff09;&…

brep2seq 论文笔记

Brep2Seq: a dataset and hierarchical deep learning network for reconstruction and generation of computer-aided design models | Journal of Computational Design and Engineering | Oxford Academic 这段文本描述了一个多头自注意力机制&#xff08;MultiHead Attenti…

【运维实战】Linux 中设置 sudo ,8个有用的 sudoers 配置!

在Linux及其他类Unix操作系统中&#xff0c;只有 root 用户能够执行所有命令并进行关键系统操作&#xff0c;例如安装更新软件包、删除程序、创建用户与用户组、修改重要系统配置文件等。 但担任 root 角色的系统管理员可通过配置sudo命令&#xff0c;允许普通系统用户执行特定…

江科大SPI串行外设接口hal库实现

hal库相关函数 初始化结构体 typedef struct {uint32_t Mode; /*SPI模式*/uint32_t Direction; /*SPI方向*/uint32_t DataSize; /*数据大小*/uint32_t CLKPolarity; /*时钟默认极性控制CPOL*/uint32_t CLKPhase; /*…