RabbitMQ养成记 (10.高级特性:死信队列,延迟队列)

news2024/11/25 12:40:53

死信队列(DLX)

这个概念 在其他MQ产品里面也是有的,只不过在Rabbitmq中稍微特殊一点
什么叫私信队列呢? 就是当消息成为 dead message之后,可以重新发到另外一台交换机,这个交换机就是DLX。

在这里插入图片描述

注意这里的有翻译歧义, 这里的DLX 指的是 交换机 ,而不是一个队列。

消息成为死信队列的三种情况

  • 队列的消息长度 到达限制。

  • 消费者拒收消息,

            channel.basicNack(deliveryTag,true,false);
            
            //这里拒收消息
            /**
             * deliveryTag 标识
             * requeue 是否打回原队列如果为false 则进入死信队列
             */
            channel.basicReject(deliveryTag,false);
        }
  • 存在消息过期设置 消息超时未消费(就是上一篇中的TTL)

我们拿这个TTL举例:

首先你在发送端 需要有2个队列 一个正常队列 一个私信队列
然后你在创建延时队列的时候 要注明 这个队列的消息一旦超时 那么送到哪个死信交换机的队列里面去:

@Configuration
public class RabbitMQConfig {
    public static final String EXCHANGE_NAME = "boot_topic_exchange";
    public static final String QUEUE_NAME_TTL = "boot_queue_ttl";

    public static final String DEAD_EXCHANGE_NAME = "dead_topic_exchange";
    public static final String DEAD_QUEUE_NAME = "dead_queue";

    //正常交换机

    @Bean("bootExchange")
    public Exchange bootExchange(){
        return ExchangeBuilder.topicExchange(EXCHANGE_NAME).durable(true).build();
    }


    @Bean("bootQueue")
    public Queue bootQueue(){
        Map<String, Object> map = new HashMap<>();
        // 设置TTL
        map.put("x-message-ttl", 20000);
        // 设置死信的目的交换机
        map.put("x-dead-letter-exchange", DEAD_EXCHANGE_NAME);
        // 设置死信交给目的交换机时的路由键
        map.put("x-dead-letter-routing-key", "boot.111");
        return QueueBuilder.durable(QUEUE_NAME_TTL).withArguments(map).build();
    }


    @Bean
    public Binding bindQueueExchange(@Qualifier("bootQueue") Queue queue,@Qualifier("bootExchange") Exchange exchange){
       return BindingBuilder.bind(queue).to(exchange).with("boot.#").noargs();
    }

    //死信交换机
    @Bean("deadExchange")
    public Exchange deadExchange(){
        return ExchangeBuilder.topicExchange(DEAD_EXCHANGE_NAME).durable(true).build();
    }

    @Bean("deadQueue")
    public Queue deadQueue(){
        return QueueBuilder.durable(DEAD_QUEUE_NAME).build();
    }

    @Bean
    public Binding bindDeadQueueExchange(@Qualifier("deadQueue") Queue queue,@Qualifier("deadExchange") Exchange exchange){
        return BindingBuilder.bind(queue).to(exchange).with("boot.*").noargs();
    }


}

好了 我们发送消息 往正常队列里面发:
在这里插入图片描述

看超时之后 它进来了:
在这里插入图片描述


·这是超时的消息进入DLX的情况
再动动手 我们实践一下 消费者拒收之后 进入死信的情况:

我们监听正常的队列 然后接受到消息之后
我们故意写一个bug 触发exception
调用basicNack方法 打回这个消息 让它 进入dlx
这里千万要注意:basicNack第三个参数要为false 才会进入dlx

如果为true 那它就会打回到正常队列 然后不停的给你发

    @RabbitListener(queues = "boot_queue_ttl")
    public void ListenerQueue(Message message,
                              @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag,
                              Channel channel) throws IOException {
        try {
            System.out.println("收到消息为"+new String(message.getBody()));

            System.out.println("处理业务逻辑。。");

//            int i =3/0; //手动制造一个bug 让程序进入异常

            channel.basicAck(deliveryTag,true);

        }catch (Exception e){
            //拒绝签收
            //这里的第三个参数表示 如果为true 消息重回到queue broker会重新发送该消息给消费端
            System.out.println(" error 处理业务逻辑失败 消息打回 进入私信队列");
            channel.basicNack(deliveryTag,true,false);
}

在这里插入图片描述

ok我们实践了两种 第三种 超过队列长度的很简单 你设一个队列长度max=10 然后for循环往里面塞进去>10 超过的就会进入dlx 这种很简单
有兴趣的好兄弟 可以自己去试一下啦
新手一定要多动手


延迟队列

什么是延迟队列 就是交换机收到消息之后 它不急着发 它等。
等到你想要它发给消费者方的时候 你再发。

假设你正在开发一个电子商务网站,并且你希望为用户提供一个订单确认后一段时间自动取消的功能。当用户下单后,订单将被发送到延迟队列中,设置一个特定的延迟时间,例如30分钟。如果在30分钟内用户未支付订单,系统将自动取消该订单。

但是问题来了 rabbitmq 中并没有提供现成的延迟队列实现,

需要我们自己去实现:

怎么实现呢 如果你理解熟悉了 前面的TTL 和死信队列之后
这个就非常非常简单了

看上面那个我们死信队列里面那个例子:
发送端向正常队列里面发数据 超时未消费。 消息就进入了死信队列,

那就很简单了 你把消费的监听队列 换成死信队列 就ok了

他就是一个延迟队列了

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

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

相关文章

基于OpenCV的人脸检测软件(含Python源码+UI界面+图文详解)

软件功能演示 摘要&#xff1a;人脸检测的目标是找出图像中所有的人脸对应的位置&#xff0c;算法的输出是人脸外接矩形在图像中的坐标&#xff0c;可能还包括姿态如倾斜角度等信息。本文详细介绍了其实现的技术原理&#xff0c;同时给出完整的Python实现代码&#xff0c;并且通…

GeoTools实战指南: 空间坐标系-地理信息科学的核心

GeoTools实战指南: 空间坐标系-地理信息科学的核心 引言 在我们的日常生活中,地图、GPS导航和地理位置服务已经变得司空见惯。但是,你有没有想过这些工具背后的工作原理呢?它们都依赖于一种称为"空间坐标系"的关键概念。本文将深入探讨空间坐标系的基础知识和其…

多线程专题(上)学习随手笔记

JMM&#xff1a;主内存物理内存线程共享&#xff0c;工作内存CPU缓存线程独占volatile&#xff1a;可见性、禁止指令重排&#xff0c;不可保证原子性&#xff1b;用于懒汉单例模式&#xff08;双重检测&#xff09;或状态标记Synchronized&#xff1a;保证代码块或方法同步化执…

Unity的URP下使用SRPBatcher

大家好&#xff0c;我是阿赵。这里继续来讲一下URP相关的东西。 这次主要说的是SRP Batcher的使用 一、在URP下实现SRP Batcher 1、设置 在我们创建的URPAsset文件的高级选项里面&#xff0c;有一个SRP Batcher的开关&#xff0c;默认就是勾上的。 2、修改shader 在把项目转…

小白白也能学会的 PyQt 教程 —— 自定义组件 Switch Button

文章目录 前言思路讲解代码部分 前言 最近在搞 Python 课程设计&#xff0c;想要搞一个好看的 UI&#xff0c;惊艳全班所有人。但打开 Qt Creator&#xff0c;Win7 风格的复古的按钮是在让我难以下手。 其次&#xff0c;我因为想要打造一个 Fluent UI 样式的设置页面&#xff…

详解c++STL—string组件

目录 一、string基本概念 1、本质 2、string和char * 区别&#xff1a; 3、特点&#xff1a; 二、string构造函数 1、构造函数原型 2、示例 三、string赋值操作 1、赋值的函数原型 2、示例 四、string字符串拼接 1、函数原型 2、示例 五、string查找和替换 1、功…

tomcat目录结构

tomcat服务器安装根目录下有很多子目录&#xff0c;这些目录的作用是&#xff1a; (1)bin&#xff1a;存放了tomcat服务器中的可执行的批处理文件(startup.bat shutdown.bat) (2)conf&#xff1a;存放了tomcat相关的配置文件(其中的server.xml是tomcat服务器核心配置文件) …

26. Pandas处理分析网站原始访问日志

Pandas处理分析网站原始访问日志 目标&#xff1a;真实项目的实战&#xff0c;探索Pandas的数据处理与分析 实例&#xff1a; 数据来源&#xff1a;我自己的wordpress博客蚂蚁学Python – 你有没有为写代码拼过命&#xff1f;那你知不知道 人生苦短&#xff0c;我用Python&am…

Python挑选出无Labelme标注文件的图片文件

Python挑选出无Labelme标注文件的图片文件 前言前提条件相关介绍实验环境Python挑选出无Labelme标注文件的图片文件代码实现输出结果 前言 本文是个人使用Python处理文件的电子笔记&#xff0c;由于水平有限&#xff0c;难免出现错漏&#xff0c;敬请批评改正。 (https://blog.…

【设计原则与思想:总结课】38 | 总结回顾面向对象、设计原则、编程规范、重构技巧等知识点

到今天为止&#xff0c;设计原则和思想已经全部讲完了&#xff0c;其中包括&#xff1a;面向对象、设计原则、规范与重构三个模块的内容。除此之外&#xff0c;我们还学习了贯穿整个专栏的代码质量评判标准。专栏的进度已经接近一半&#xff0c;马上就要进入设计模式内容的学习…

Python: 生成ubuntu apt镜像地址

文章目录 1. 目的2. 设计3. 实现4. 调用5. 参考 1. 目的 每次新配置 Ubuntu 系统&#xff0c;免不了配置 apt 源。尽管可以通过 GUI 界面进行选择&#xff0c;但自动化程度不够&#xff0c;不同桌面&#xff08;Unity/Gnome/KDE&#xff09;下的界面也不太一样&#xff1b; 使…

Java基础-sleep和wait的区别

本文介绍Java中sleep和wait方法的使用区别 文章目录 sleep()wait()sleep()和wait()对比区别相同点 sleep() 查看sleep方法&#xff0c;可见其是static native方法 public static native void sleep(long millis) throws InterruptedException;sleep()方法需要指定等待的时间。…

HTTP第14讲——HTTP传输大文件的方法

背景 HTTP 可以传输很多种类的数据&#xff0c;不仅是文本&#xff0c;也能传输图片、音频和视频。 早期互联网上传输的基本上都是只有几 K 大小的文本和小图片&#xff0c;现在的情况则大有不同。网页里包含的信息实在是太多了&#xff0c;随随便便一个主页 HTML 就有可能上百…

java常用集合

java集合又是一个新世界了&#xff0c;从前在我刚接触java的时候&#xff0c;一直在纠结 集合这东西到底有啥用&#xff0c;后来代码写的多了。才开始学习集合 集合也叫容器。顾名思意 就是存放对象的器皿。 主要是由两大接口派生而来 &#xff1a;一个是 Collecton接口&#…

LeetCode高频算法刷题记录2

文章目录 1. 最大子数组和【简单】1.1 题目描述1.2 解题思路1.3 代码实现 2. 合并两个有序链表【简单】2.1 题目描述2.2 解题思路2.3 代码实现 3. 两数之和【简单】3.1 题目描述3.2 解题思路3.3 代码实现 4. 二叉树的层序遍历【中等】4.1 题目描述4.2 解题思路4.3 代码实现 5. …

代码随想录算法训练营第四十二天 | 背包问题

背包问题 理论 基础&#xff1a;二维 文档讲解&#xff1a;代码随想录 (programmercarl.com) 视频讲解&#xff1a;带你学透0-1背包问题&#xff01;| 关于背包问题&#xff0c;你不清楚的地方&#xff0c;这里都讲了&#xff01;| 动态规划经典问题 | 数据结构与算法_哔哩哔哩…

Revit SDK:ErrorHandling

前言 本文介绍 Revit 的错误处理机制。 内容 程序员对错误处理的定义和理解 程序的错误处理机制可以分为两种类型&#xff1a;错误返回码和异常捕捉。 错误返回码是指在程序中遇到错误时&#xff0c;通过函数返回值来表明错误的类型和信息。错误返回码可以在程序中被预测和…

MySQL数据落盘原理(data page、redo log、undo log、binlog、xa-2pc等源码分析)

文章目录 前言一、Innodb如何作为MySQL插件的二、page cleaner thread三、Update操作源码梳理1、生成undo log2、更新数据3、生成redo log 四、MTR与将脏页添加到Flush List1、MTR2、脏页添加到Flush List 五、事务提交1、xa-prepare2、xa-commit2.1、process_flush_stage_queu…

概率统计与计算机技术的联系及在生活当中的应用研究

title: 概率统计与计算机技术的联系及在生活当中的应用研究 date: 2023-05-16 11:42:26 tags: 题目&#xff1a;概率统计与计算机技术的联系及在生活当中的应用研究 摘 要 概率论与数理统计是研究随机现象统计规律性的一门学科&#xff0c;是理工科各专业的一门重要的基础课程…

shell免交互

shell免交互 Here Document 免交互 使用I/O重定向的方式将命令列表提供给交互式程序或命令&#xff0c;比如 ftp、cat 或 read 命令。 是标准输入的一种替代品可以帮助脚本开发人员不必使用临时文件来构建输入信息&#xff0c;而是直接就地生产出一个“文件”并用作“命令”的…