死信队列小结

news2025/1/8 12:02:05

        死信队列是RabbitMQ中非常重要的一个特性。简单理解,他是RabbitMQ对于未能正常消费的消息进行的 一种补救机制。死信队列也是一个普通的队列,同样可以在队列上声明消费者,继续对消息进行消费处理。 对于死信队列,在RabbitMQ中主要涉及到几个参数

重点:核心就在这里:

x-dead-letter-exchange: mirror.dlExchange   对应的死信交换机

x-dead-letter-routing-key: mirror.messageExchange1.messageQueue1 死信交换机routingkey
x-message-ttl:3000 消息过期时间

durable: true 持久化,这个是必须的。

如果依然不知道在哪里设置,看下图:创建一个队列的时候有参数可以设置

在这里,x-dead-letter-exchange指定一个交换机作为死信交换机,然后x-dead-letter-routing-key指定交 换机的RoutingKey。而接下来,死信交换机就可以像普通交换机一样,通过RoutingKey将消息转发到对应 的死信队列中。

目录

1、何时会产生死信

2、死信队列的配置方式

3、关于参数x-dead-letter-routing-key

4、如何确定一个消息是不是死信

5、基于死信队列实现延迟队列


1.何时会产生死信

有以下三种情况,RabbitMQ会将一个正常消息转成死信:

一:消息被消费者确认拒绝。消费者把requeue参数设置为false,也就是不重新入队,并且在消费后,向RabbitMQ返回 拒绝。channel.basicReject或者channel.basicNack。

二:消息达到预设的TTL时限还一直没有被消费。

三:消息由于队列已经达到最长长度限制而被丢掉。

TTL即最长存活时间 Time-To-Live 。消息在队列中保存时间超过这个TTL,即会被认为死亡。死亡的消 息会被丢入死信队列,如果没有配置死信队列的话,RabbitMQ会保证死了的消息不会再次被投递,并 且在未来版本中,会主动删除掉这些死掉的消息。 设置TTL有两种方式,一是通过配置策略指定,另一种是给队列单独声明TTL

策略配置方式 - Web管理平台配置 或者 使用指令配置 60000为毫秒单位 在声明队列时指定 - 同样可以在Web管理平台配置,也可以在代码中配置:

Map<String, Object> args = new HashMap<String, Object>();

args.put("x-message-ttl", 60000);

channel.queueDeclare("myqueue", false, false, false, args);

2、死信队列的配置方式

RabbitMQ中有两种方式可以声明死信队列,一种是针对某个单独队列指定对应的死信队列。另一种就是以 策略的方式进行批量死信队列的配置。 针对多个队列,可以使用策略方式,配置统一的死信队列。

rabbitmqctl set_policy DLX ".*" '{"dead-letter-exchange":"my-dlx"}' --apply-to queues

针对队列单独指定死信队列的方式主要是之前提到的三个属性。

channel.exchangeDeclare("some.exchange.name", "direct");

Map<String, Object> args = new HashMap<String, Object>();

args.put("x-dead-letter-exchange", "some.exchange.name");

channel.queueDeclare("myqueue", false, false, false, args);

这些参数,也可以在RabbitMQ的管理页面进行配置。另外,你会注意到,在对队列进行配置时,只有Classic经典队列和Quorum仲裁队列才能配置死信队列, 而目前Stream流式队列,并不支持配置死信队列。

3、关于参数x-dead-letter-routing-key

死信在转移到死信队列时,他的Routing key 也会保存下来。但是如果配置了x-dead-letter-routing-key这 个参数的话,routingkey就会被替换为配置的这个值。 另外,死信在转移到死信队列的过程中,是没有经过消息发送者确认的,所以并不能保证消息的安全性。

4、如何确定一个消息是不是死信

消息被作为死信转移到死信队列后,会在Header当中增加一些消息。在官网的详细介绍中,可以看到很多 内容,比如时间、原因(rejected,expired,maxlen)、队列等。然后header中还会加上第一次成为死信的三个 属性,并且这三个属性在以后的传递过程中都不会更改。

x-first-death-reason

x-first-death-queue

x-first-death-exchange

5、基于死信队列实现延迟队列

其实从前面的配置过程能够看到,所谓死信交换机或者死信队列,不过是在交换机或者队列之间建立一种 死信对应关系,而死信队列可以像正常队列一样被消费。他与普通队列一样具有FIFO的特性。对死信队列的 消费逻辑通常是对这些失效消息进行一些业务上的补偿

RabbitMQ中,是不存在延迟队列的功能的,而通常如果要用到延迟队列,就会采用TTL+死信队列的方 式来处理。

最后,用代码实现一个延时队列的功能:Springboot +rabbitmq

配置类:



@Configuration
public class DeadLetterMsg {

    @Bean
    public Queue orderQueue(){
        Map<String,Object> params = new HashMap<>();
        params.put("x-dead-letter-exchange", MyConstants.DEAD_LETTER_EXCHANGE);
        params.put("x-dead-letter-routing-key",MyConstants.DEAD_KEY);
        params.put("x-message-ttl",30000);
        return new Queue(MyConstants.ORDER_QUEUE,true,false,false,params);
    }

    @Bean
    public DirectExchange orderDirectExchange(){
        return new DirectExchange(MyConstants.ORDER_EXCHANGE);
    }

    @Bean
    public Binding orderBinding(){
        return BindingBuilder.bind(orderQueue()).to(orderDirectExchange()).with(MyConstants.ORDER_KEY);
    }

    @Bean
    public Queue deadQueue(){
        return new Queue(MyConstants.DEAD_LETTER_QUEUE,true,false,false);
    }

    @Bean
    public DirectExchange deadDirectExchange(){
        return new DirectExchange(MyConstants.DEAD_LETTER_EXCHANGE);
    }

    @Bean
    public Binding deadBinding(){
        return BindingBuilder.bind(deadQueue()).to(deadDirectExchange()).with(MyConstants.DEAD_KEY);
    }
}

发送


@RestController
@Api(value = "自己学习rabbitmq",tags = "学习mq动手")
public class XssProducer {

    @Autowired
    private RabbitTemplate rabbitTemplate ;


    @RequestMapping(value = "/sendOrder",method = RequestMethod.GET)
    @ApiOperation(value="订单",notes="sendTopic")
    @ApiImplicitParam(name="msg",value="要发送的信息",defaultValue = "你好,订单")
    public void sendOrder(String msg){

        int random = new Random().nextInt();
        rabbitTemplate.send(MyConstants.ORDER_EXCHANGE,MyConstants.ORDER_KEY
                ,new Message(("订单信息No:123456" +random).getBytes(StandardCharsets.UTF_8)));
    }
}


消费死信队列:

@Component
public class DeadConsumer {

    @RabbitListener(queues = {MyConstants.DEAD_LETTER_QUEUE})
    public void receiveDeadLetterQueue(String message){
        System.out.println(" 死信队列中的消息为:" + message);
    }
}

运行代码就会发现30s后会收到之前发送到orderQueue的信息。注意:这30s中内orderQueue别被消费了。

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

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

相关文章

Spring 是什么?IoC 和 DI的区别

1. Spring 是什么?2. IoC是什么&#xff1f; 2.DI概念说明 1. Spring 是什么? 我们通常讲的Spring指的是Spring Framework(Spring框架),它是一个开源的框架,有着活跃而庞大的社区,这也是它之所谓经久不衰的原因。官方的解读是:Spring官网 翻译过来就是:Spring使Java编程对每…

学会这5个步骤,就能轻轻松松地获取代码覆盖率报告

目录 前言&#xff1a; 1、创建main函数的test文件 2、插桩方式编译源码 3、运行主服务 4、执行测试用例 5、优雅退出主服务&#xff0c;并生成覆盖率报告 前言&#xff1a; 代码覆盖率报告可以帮助我们了解测试用例的质量和覆盖程度。 小编前期所测项目多为go语言研发&…

《C++高级编程》读书笔记(一:C++和标准库速成)

1、参考引用 C高级编程&#xff08;第4版&#xff0c;C17标准&#xff09;马克葛瑞格尔 2、建议先看《21天学通C》 这本书入门&#xff0c;笔记链接如下 21天学通C读书笔记&#xff08;文章链接汇总&#xff09; 1. C 基础知识 1.1 小程序 “hello world” // helloworld.cpp…

开源项目合集......

likeshop开源商城系统&#xff0c;公众号商城、H5商城、微信小程序商城、抖音小程序商城、字节小程序商城、头条小程序商城、安卓App商城、苹果App商城代码全开源&#xff0c;免费商用。 适用场景&#xff1a;B2C商城、新零售商城、社交电商商城、分销系统商城、小程序商城、商…

循环链表的创建

循环链表的介绍及创建&#xff08;C语言代码实现&#xff09; 点击打开在线编译器&#xff0c;边学边练 循环链表概念 对于单链表以及双向链表&#xff0c;其就像一个小巷&#xff0c;无论怎么样最终都能从一端走到另一端&#xff0c;然而循环链表则像一个有传送门的小巷&…

力扣 912. 排序数组

文章目录 一、题目描述二、题解1.快速排序2.堆排序3.二路归并排序 一、题目描述 给你一个整数数组 nums&#xff0c;请你将该数组升序排列。 示例 1&#xff1a; 输入&#xff1a;nums [5,2,3,1] 输出&#xff1a;[1,2,3,5]示例 2&#xff1a; 输入&#xff1a;nums [5,1,1…

精细消费 年轻人和父母的奇妙交汇

日本社会学家三浦展结合对日本“311”大地震后的社会观察&#xff0c;提出了“第四消费时代”&#xff0c;即人们在经历了消费社会充分的发展过程之后&#xff0c;社会上逐渐兴起了低欲望、乐于共享、重视环保的消费理念。 在当时&#xff0c;主流观点普遍认为中国还处于大众化…

JWT单点登录

单点登录 文章目录 单点登录零、用户模块内容以及设计一、问题的提出二、单点登录SSO1.1 什么是单点登录1.2 单点登录的技术实现机制 二、远程调用方式RPC三、JWT的使用3.1 session的使用原理3.2 JWT介绍3.3 JWT原理3.4 JWT的使用 四、CAS实现单点登录的原理四、CAS的安装和代码…

十二、进程间通信

目录 目录 零、前置知识 一、什么是进程间通信 &#xff08;一&#xff09;含义 &#xff08;二&#xff09;发展 &#xff08;三&#xff09;类型 1.管道 2.System V IPC 3.POSIX IPC 二、为什么要有进程间通信 三、怎么进行进程间通信 &#xff08;一&#xff09;…

Snipaste工具推荐

Snipaste Snipaste 不只是截图&#xff0c;善用贴图功能将帮助你提升工作效率&#xff01; 新用户&#xff1f; 截图默认为 F1&#xff0c;贴图为 F3&#xff0c;然后请对照着 快捷键列表 按一遍&#xff0c;体会它们的用法&#xff0c;就入门啦&#xff01; 遇到了麻烦&…

Java通过Ip2region实现IP定位

我们在一些短视频平台上可以看到,视频作者或评论区可以显示IP地址,这其实就是根据IP获取到的我们可以通过一些在线网站就可以看到我们当前的公网IP和IP定位,最近有个需求也需要通过请求获取客户端的IP和IP的定位,于是通过一系列的百度,最终选择使用Ip2region这个工具库来进行定…

flutter的自定义系列雷达图

自定义是flutter进阶中不可缺少的ui层知识点&#xff0c;这里我们来总结下&#xff1a; 在Flutter中&#xff0c;自定义绘制通常是通过使用CustomPaint和CustomPainter来实现的。 创建CustomPaint组件 首先&#xff0c;需要创建一个CustomPaint组件。CustomPaint是一个Widge…

MobPush 厂商通道申请指南

华为厂商申请 创建应用 登录华为开发者联盟&#xff0c;注册您的应用&#xff0c;在应用信息中获取APP ID和Client Secret 配置SHA256证书指纹 在华为开发者联盟配置SHA256证书指纹。获取及配置请参见华为官方文档配置AppGallery Connect 设置消息回执 集成华为厂商通道SDK…

带你了解二进制

目录 视频参考&#xff1a; 讲解&#xff1a;​编辑 运算&#xff1a; 1001&#xff08;二进制&#xff09; 9&#xff08;十位数&#xff09;1111&#xff08;二进制&#xff09; 15&#xff08;十位数&#xff09;11001&#xff08;二进制&#xff09; 25&#xff08;…

第二章 搭建TS环境

搭建 TypeScript 的开发环境。一个舒适、便捷且顺手的开发环境&#xff0c;不仅能大大提高学习效率&#xff0c;也会对我们日常的开发工作有很大帮助。 这一节我们就来介绍 VS Code 下的 TypeScript 环境搭建&#xff1a;插件以及配置项。对于 TS 文件的执行&#xff0c;我们会…

设计模式(十):结构型之外观模式

设计模式系列文章 设计模式(一)&#xff1a;创建型之单例模式 设计模式(二、三)&#xff1a;创建型之工厂方法和抽象工厂模式 设计模式(四)&#xff1a;创建型之原型模式 设计模式(五)&#xff1a;创建型之建造者模式 设计模式(六)&#xff1a;结构型之代理模式 设计模式…

备战2月面试8家大厂,成功上岸字节(Java岗)定级T2-2,分享一下我的面试心得

最近在公众号上看到一位道友的字节面经&#xff0c;可以说是深有感触了&#xff01; 他的背景是杭州某中厂的Java后端开发&#xff0c;本科毕业5年&#xff0c;最近2个月面试了PDD、小红书、字节等多个大厂。几乎都拿到了Offer&#xff0c;最终选择了字节2-2。以下是他的一些分…

Navicat对postgresql导入导出的坑

Navicat导出postgresql中的表&#xff0c;再新建数据库导入时通常会报错&#xff0c;往往是因为自增id导致的 可以看到&#xff0c;再次导入时会报错&#xff01; 解决办法如下&#xff1a; 解决办法&#xff1a; 重新导入&#xff0c;并执行以下命令&#xff1a;&#xff08…

Python从入门到精通_第0讲_Python的学习路线整理

写在最前&#xff1a; 为什么开这个专栏&#xff1a; 之前我做过一个专栏&#xff0c;专门介绍Python爬虫技术&#xff0c;这一专栏收获了很多朋友们的点赞收藏和关注。但是在爬虫技术专栏中&#xff0c;对于Python语言本身的讲解并不是很细致&#xff0c;由于Python在爬虫、数…

Unity 安装 wwise

先下载 https://www.audiokinetic.com/zh/download 安装的时候要选sdk 就是20g的那个 然后运行 选择unity 可以看到这个界面 好&#xff0c;现在开始要安装离线包 直接项目里点 第二个 装好后 他会提示你 无法找到unity安装的地址 1 打开你的 unity 编辑器 2 在unity安装的…