MQ高级(二)死信交换机

news2024/11/18 5:55:32

一、初识死信交换机(P159)

当一个队列中的消息满足下列情况之一时,可以成为死信(dead letter)

(1)消费者使用basic.reject或 basic.nack声明消费失败,并且消息的requeue参数设置为false

(2)消息是一个过期消息,超时无人消费

(3)要投递的队列消息堆积满了,最早的消息可能成为死信

如果该队列配置了dead-letter-exchange属性,指定了一个交换机,那么队列中的死信就会投递到这个交换机中,而这个交换机称为死信交换机(Dead Letter Exchange,简称DLX)。

 

二、TTL

TTL,也就是Time-To-Live。如果一个队列中的消息TTL结束仍未消费,则会变为死信,ttl超时分为两种情况:

(1)消息所在的队列设置了存活时间

(2)消息本身设置了存活时间

 

我们声明一组死信交换机和队列,基于注解方式:

@Slf4j
@Component
public class SpringRabbitListener {
 
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = "dl.queue", durable = "true"),
            exchange = @Exchange(name = "dl.direct"),
            key = "dl"
    ))
    public void listenDlQueue(String msg) {
        log.info("消费者接收到了dl.queue的延迟消息");
    }

}

要给队列设置超时时间,需要在声明队列时配置 x-message-ttl 属性:

@Configuration
public class TTLMessageConfig {

    @Bean
    public DirectExchange ttlDirectExchange(){
        return new DirectExchange("ttl.direct");
    }

    @Bean
    public Queue ttlQueue(){
        return QueueBuilder
                .durable("ttl.queue")
                .ttl(10000)
                .deadLetterExchange("dl.direct")
                .deadLetterRoutingKey("dl")
                .build();
    }

    @Bean
    public Binding ttlBinding(){
        return BindingBuilder.bind(ttlQueue()).to(ttlDirectExchange()).with("ttl");
    }
}

发送消息时,给消息本身设置超时时间

    @Test
    public void testTTLMessage() {
        // 1.准备消息
        Message message = MessageBuilder
                .withBody("hello, ttl messsage".getBytes(StandardCharsets.UTF_8))
                .setDeliveryMode(MessageDeliveryMode.PERSISTENT)
                .setExpiration("5000")
                .build();
        // 2.发送消息
        rabbitTemplate.convertAndSend("ttl.direct", "ttl", message);
        // 3.记录日志
        log.info("消息已经成功发送!");
    }

队列和消息设置 ttl 属性,两者共存时,以时间短的 ttl 为准。

三、延迟队列

利用TTL结合死信交换机,我们实现了消息发出后,消费者延迟收到消息的效果。这种消息模式就称为延迟队列(Delay Queue)模式。

延迟队列的使用场景包括:

(1)延迟发送短信

(2)用户下单,如果用户在15 分钟内未支付,则自动取消

(3)预约工作会议,20分钟后自动通知所有参会人员

因为延迟队列的需求非常多,所以RabbitMQ的官方也推出了一个插件,原生支持延迟队列效果。

1. SpringAMQP使用延迟队列插件

DelayExchange的本质还是官方的三种交换机,只是添加了延迟功能。因此使用时只需要声明一个交换机,交换机的类型可以是任意类型,然后设定delayed属性为true即可。

基于注解方式:

@Slf4j
@Component
public class SpringRabbitListener {


    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = "delay.queue", durable = "true"),
            exchange = @Exchange(name = "delay.direct", delayed = "true"),
            key = "delay"
    ))
    public void listenDelayExchange(String msg) {
        log.info("消费者接收到了delay.queue的延迟消息");
    }
}

基于java代码的方式:

 

然后我们向这个delay为true的交换机中发送消息,一定要给消息添加一个header:x-delay,值为延迟的时间,单位为毫秒:

    @Test
    public void testSendDelayMessage() throws InterruptedException {
        // 1.准备消息
        Message message = MessageBuilder
                .withBody("hello, ttl messsage".getBytes(StandardCharsets.UTF_8))
                .setDeliveryMode(MessageDeliveryMode.PERSISTENT)
                .setHeader("x-delay", 5000)
                .build();
        // 2.准备CorrelationData
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        // 3.发送消息
        rabbitTemplate.convertAndSend("delay.direct", "delay", message, correlationData);

        log.info("发送消息成功");
    }

判断是否是延迟消息。是一个延迟消息,忽略这个错误提示

@Slf4j
@Configuration
public class CommonConfig implements ApplicationContextAware {

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        // 获取RabbitTemplate对象
        RabbitTemplate rabbitTemplate = applicationContext.getBean(RabbitTemplate.class);
        // 配置ReturnCallback
        rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> {
            // 判断是否是延迟消息
            Integer receivedDelay = message.getMessageProperties().getReceivedDelay();
            if (receivedDelay != null && receivedDelay > 0) {
                // 是一个延迟消息,忽略这个错误提示
                return;
            }
            // 记录日志
            log.error("消息发送到队列失败,响应码:{}, 失败原因:{}, 交换机: {}, 路由key:{}, 消息: {}",
                     replyCode, replyText, exchange, routingKey, message.toString());
            // 如果有需要的话,重发消息
        });
    }
}

延迟队列插件的使用步骤包括哪些?

(1)声明一个交换机,添加delayed属性为true

(2)发送消息时,添加x-delay头,值为超时时间

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

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

相关文章

使用opencv截取旋转框目标

使用opencv截取旋转框目标1、第一种方法2、第二种方法3、两种方法的简单对比4、opencv 最小面积矩形返回角度的理解4.1、version4.2之前4.1、version4.2之后本文列举了两种方法,使用的数据如图,用的是改版rolabelimg标注的标注文件有四个点的坐标: 1、…

mybatis详述

文章目录一、引言1.1 什么是框架?1.2 什么是ORM框架?1.3使用JDBC完成ORM操作的缺点?二、MyBatis框架2.1概念2.2 MyBatis开发步骤2.3 如何编写mybatis映射文件(规范)三、mybatis-config.xml 配置补充四、mybatis接口与映射文件指令间 传递参数4.1 传递…

安卓APP源码和设计报告——北京旅游系统

目 录 一、概述11 1.1 课题描述11 1.2 需求分析22 1.3 开发环境33 二、系统分析与概要设计55 2.1 系统功能分析55 2.2 系统模块结构图66 2.3 数据库表的设计66 三、北京旅游系统的登录功能模块的详细设计88 3.1 登录模块的功能描述88 3.2 登录模块的界面布局的设计9…

185: vue+openlayers 引用hover插件,展示各种鼠标cursor样式

第185个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+openlayers中使用hover效果,这里是引用了一个hover插件。鼠标对应到相应的feature中时候,获取其类型,并且设定不同的鼠标样式。 直接复制下面的 vue+openlayers源代码,操作2分钟即可运行实现效果; 注意如果Ope…

一篇知晓-内存竟被”无意“破坏,真相究竟如何?

内存是C/C程序员的好帮手,我们通常说C/C程序性能更高其原因之一就在于可以自己来管理内存,然而计算机科学中没有任何一项技术可以包治百病,内存问题也给C/C程序员带来无尽的烦恼。 野指针、数组越界、错误的内存分配或者释放、多线程读写导致…

kotlin之hello world

如果你想一个人写全栈的话,Kotlin Multiplatform (以下简称MPP)是目前这个星球上最好的选择,没有之一。 Kotlin 是一种在 Java 虚拟机上运行的静态类型编程语言,被称之为 Android 世界的Swift,由 JetBrain…

CTFSHOW web入门 java反序列化篇(更新中)

在做这部分题前,推荐大家先去学习下java反序列化,尤其是CC链 可以看下两个系列视频,收获颇多 https://space.bilibili.com/2142877265/channel/collectiondetail?sid29805&ctype0 https://www.bilibili.com/video/BV16h411z7o9/?spm_i…

手写Spring2(实现 Bean 的定义、注册、获取)

文章目录前言本章目标一、实现1、项目结构2、BeanFactory-bean工厂3、BeanDefinition -bean定义4、单例注册接口定义和实现-SingletonBeanRegistry 、DefaultSingletonBeanRegistry5、AbstractBeanFactory-抽象bean工厂类(定义模板方法)6、AbstractAutowireCapableBeanFactory-…

python配置环境问题记录------2022/12/07

python配置问题记录1、版本匹配的问题2、指令安装相关依赖包3、pycharm指定解释器4、运行网络模块5、总结1、版本匹配的问题 到官网下载合适的版本(注意位数,我这里选的是64位),pycharm选的是21年版本的,太新的话会有…

【C++】异常exception

目录 一.C语言错误处理方式 1.assert(断言) 2.返回/设置错误码 二.C异常的概念与使用 1.异常的概念 2.异常的使用 三.自定义异常体系MyException 四.异常的重新抛出 五.异常安全问题 六.异常规范 七.异常的优缺点对比 一.C语言错误处理方式 一个C语言程序, 在运行期…

回归分析与相关分析的区别和联系

在本节中,我们将首先讨论相关性分析,它用于量化两个连续变量之间的关联(例如,独立变量与因变量之间或两个独立变量之间)。 最近我们被客户要求撰写关于回归分析与相关分析的研究报告,包括一些图形和统计输…

软件测试经验与教训

下面精选出10条,和大家分享。 01 测试人员是项目的前灯 一个项目就像是一次陆上旅行。有些项目很简单、很平常,就像是大白天开车去商店买东西。但是大多数值得开发的项目更像是夜间在山里开越野卡车,这些项目需要前灯,而测试员要照…

直播带货行业如何入局?先了解一下直播商城源码吧

直播行业的爆火已经持续了多个年头,直到今天,在人们的生活中依然有着举足轻重的地位,它通过多元化的方案为许多行业带来了新的思路,特别是与传统商业所结合的“直播电商”、“直播商城”的卖货新形式,让多方因此而受益…

数理化解题研究杂志社数理化解题研究编辑部2022年第30期目录

教学改革探索 信息技术下中职数学“翻转课堂”教学创新策略研究 李宇仙; 2-4《数理化解题研究》投稿:cn7kantougao163.com 基于高中数学核心素养的错题讲评课之探索与实践 施浩妹; 17-20 高中数学“问题导学”模式的实践研究 吴金桥; 21-23 立于神而…

【测试沉思录】21. 如何用 JMeter 编写性能测试脚本?

作者:宋赟 编辑:毕小烦 Apache JMeter 应该是应用最广泛的性能测试工具。怎么用 JMeter 编写性能测试脚本? 1. 编写 HTTP 性能测试脚本 STEP 1. 添加 HTTP 请求 STEP 2. 了解配置信息 HTTP 请求各项信息说明(以 JMeter 5.1 为例…

【强化学习论文合集】十.2018智能体和多智能体系统国际联合会议论文(AAMAS2018)

强化学习(Reinforcement Learning, RL),又称再励学习、评价学习或增强学习,是机器学习的范式和方法论之一,用于描述和解决智能体(agent)在与环境的交互过程中通过学习策略以达成回报最大化或实现特定目标的问题。 本专栏整理了近几年国际顶级会议中,涉及强化学习(Rein…

十四、SpringBoot-自动装配原理

十四、SpringBoot-自动装配原理 SpringBoot与Spring比较起来,优化的点主要有: 自动配置:是一个运行时(应用程序启动时)的过程,考虑了众多因素,才决定Spring配置应该用哪个,不该用哪…

软件测试基础丨测试工程师之间要善于发现闪光点——测试理念篇

测试理念有多种,有一些理念,深藏于我的心中, 而这些理念,您或许偶尔想到,却没有说出,或许您感受到了,却因为工作生活的忙碌,没有将其背后的含义想具体, 在此我非常愿意和…

零基础小白hadoop分布式集群环境搭建(超详细)

搭建集群所需要安装包 虚拟机、ubuntu镜像文件、jdk安装包、hadoop安装包 百度云盘地址: 链接:https://pan.baidu.com/s/1ejVamlrlyoWtJRo1QQqlsA提取码:fcqm 本文的环境是两台windows笔记本,在每台笔记本上安装一个虚拟机&…

超详细的水果FL Studio21最新版更新全功能详细介绍!80项更新与改进!

万众期待的 FL Studio 21 版本将于正式发布上线,目前在紧锣密鼓的安排上线中,届时所有购买正版 FL Studio 的用户,都可以免费升级到21版!按照惯例,本次新版也会增加全新插件,来帮助大家更好地创作。今天先给…