【RabbitMQ】SpringBoot整合RabbitMQ实现延迟队列、TTL、DLX死信队列

news2024/11/24 18:49:16

目录

一、TTL

1、什么是TTL

2、设置TTL的两种方式

3、控制台设置TTL

4、SpringBoot实现两种方式设置TTL

1.给消息设置过期时间

2.给队列设置过期时间

二、DLX死信队列

1、什么是死信交换机与死信队列

2、消息何时会成为死信

3、队列如何绑定死信交换机与死信队列

4、SpringBoot实现死信队列

三、延迟队列

1、什么是延迟队列

2、使用场景

四、SpringBoot整合RabbitMQ实现延迟队列案例之订单超时

1、实现思路

2、代码实现

一、TTL

1、什么是TTL

TTL(Time To Live):存活时间/过期时间,在RabbitMQ里表示消息从生产者到服务器后该消息的存活时间,一旦到达时长该消息就会被自动清除

2、设置TTL的两种方式

在RabbitMQ里有两种设置过期时间的方式,分别是给消息单独设置时长、给队列设置过期时长,该队列里所有的消息都是该时长,当两种都设置了时以时间短的为准。消息在队列里到达过期时长并不是马上去删除,如果马上删除需要服务器去无时不刻的扫描或者去做其他算法来检测,导致服务器性能变低,RabbitMQ的做法是当消息到达队顶时判断消息是否过期,如果过期则删除,没过期则给消费者

3、控制台设置TTL

我们打开控制台,在创建队列时如下图

点击此处即可设置时长单位是毫秒,此时发送消息到该队列在设定的过期时间后观察该队列消息数为0,消息由于过期被丢失 

4、SpringBoot实现两种方式设置TTL

      在实现之前我们需要去创建一个配置类并在里创建队列

关于此处 创建交换机与队列代码在之前文章里有提到 

1.给消息设置过期时间

在发送消息时使用该匿名内部类设置过期时间

2.给队列设置过期时间

该种方式只需在配置类创建队列时指定即可

在此处指定时长即可,我们给创建好的队列发送给消息队列收到消息后指定的时间后会将该消息丢弃

二、DLX死信队列

1、什么是死信交换机与死信队列

死信队列英文缩写DLX,Dead Letter Exchange(死信交换机)当消息成为死消息后,可以被重新发送到另一个交换机,这个交换机就是死信交换机,在由该交换机转发给相应的死信队列

2、消息何时会成为死信

那么什么是消息才会变成死信呢,有以下三种情况:队列长度达到最大限制此时收到的消息就是死信或者被消费者拒收且消费者不设置重回队列的消息就是死信以及在原队列超过时间限制的消息

3、队列如何绑定死信交换机与死信队列

正常队列绑定死信交换机后,他的死信就可以由死信交换机转发到死信队列。在创建普通队列时我们需要绑定的有死信交换机与死信队列的路由,此时普通队列就类似生产者,生产者发送消息时需要指定路由此处也相同

4、SpringBoot实现死信队列

在实现死信队列时,我们需要创建正常队列与正常交换机,然后创建死信交换机与死信队列。然后修改创建普通队列的代码绑定死信交换机与死信队列

我们先来创建普通队列与普通交换机并进行绑定以及死信交换机与死信队列

package com.example.demo.delay;

import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class DelayQueueConfig {
    // 1.创建正常队列交换机与私信交换机与队列
    public static final String NOR_QUEUE = "norQueue";   // 普通队列
    public static final String NOR_EXCHANGE = "norEx";   // 普通交换机
    public static final String DLX_QUEUE = "dlxQueue";   // 死信队列
    public static final String DLX_EXCHANGE = "dlxEx";   // 死信交换机
    public static final String DLX_ROUTING_KEY = "dlx";  // 死信队列路由
    public static final String NOR_ROUTING_KEY = "nor";  // 普通队列路由

    @Bean
    public Queue norQueue(){
        // 创建普通队里绑定私信交换机与发送到死信队列的路由
        return QueueBuilder.durable(NOR_QUEUE).ttl(10000).build();
    }

    @Bean
    public DirectExchange norEx() {
        // 创建普通交换机
        return ExchangeBuilder.directExchange(NOR_EXCHANGE).build();
    }

    @Bean
    public Binding bindingNor(@Qualifier("norQueue")Queue norQueue,@Qualifier("norEx")DirectExchange norEx) {
        // 将普通队里与普通交换机绑定
        return BindingBuilder.bind(norQueue).to(norEx).with(NOR_ROUTING_KEY);
    }

    @Bean
    public Queue dlxQueue() {
        // 创建死信队列
        return QueueBuilder.durable(DLX_QUEUE).build();
    }

    @Bean
    public DirectExchange dlxEx() {
        // 创建死信交换机
        return ExchangeBuilder.directExchange(DLX_EXCHANGE).build();
    }

    @Bean
    public Binding bindingDLX(@Qualifier("dlxQueue") Queue dlxQueue,@Qualifier("dlxEx")DirectExchange dlxEx) {
        // 将死信队列与死信交换机绑定
        return BindingBuilder.bind(dlxQueue).to(dlxEx).with(DLX_ROUTING_KEY);
    }

}

此时我们需要修改创建普通队列的代码让他与死信交换机进行绑定并设置死信要到达的死信队列的路由  

这个时候我们发送一条数据到普通队列,经过指定的时间后变为死信就会进入死信队列,后续可以创建消费者去消费死信队列里的信息 

三、延迟队列

1、什么是延迟队列

在RabbitMQ里当消息到达队列后不会立马被消费者消费,而是到达指定的时间才会被消费。

2、使用场景

比如我们可以在用户注册后的第n天给用户发送邮件,或者当用户下单后10分钟以内如果没有被支付就将订单信息回滚

四、SpringBoot整合RabbitMQ实现延迟队列案例之订单超时

1、实现思路

在RabbitMQ里没有提供延迟队列,但是我们发现上述场景类似我们在前面提到的死信队列,我们可以通过TTL+DLX也就是死信队列与设置消息过期时长来实现延迟队列,拿订单超时未支付来举例子,当用户下单后我们将订单信息发个MQ,并设置该订单信息的存活时长为10分钟,10分钟后它就会变为死信进入死信队列,此时我们只需要监听死信队列,然后拿到信息后去数据库查询是否支付,如果没有支付就回滚库存

2、代码实现

我们首先需要创建普通队列、普通交换机、死信队列、死信交换机然后普通队列绑定死信交换机并设置消息存活时长为10分钟,代码与上面实现死信队列类型

package com.example.demo.delay;

import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class DelayQueueConfig {
    // 1.创建正常队列交换机与私信交换机与队列
    public static final String NOR_QUEUE = "norQueue";   // 普通队列
    public static final String NOR_EXCHANGE = "norEx";   // 普通交换机
    public static final String DLX_QUEUE = "dlxQueue";   // 死信队列
    public static final String DLX_EXCHANGE = "dlxEx";   // 死信交换机
    public static final String DLX_ROUTING_KEY = "dlx";  // 死信队列路由
    public static final String NOR_ROUTING_KEY = "nor";  // 普通队列路由

    @Bean
    public Queue norQueue(){
        // 创建普通队里绑定私信交换机与发送到死信队列的路由
        return QueueBuilder.durable(NOR_QUEUE).ttl(时长).
                deadLetterExchange(DLX_EXCHANGE).deadLetterRoutingKey(DLX_ROUTING_KEY).build();
    }

    @Bean
    public DirectExchange norEx() {
        // 创建普通交换机
        return ExchangeBuilder.directExchange(NOR_EXCHANGE).build();
    }

    @Bean
    public Binding bindingNor(@Qualifier("norQueue")Queue norQueue,@Qualifier("norEx")DirectExchange norEx) {
        // 将普通队里与普通交换机绑定
        return BindingBuilder.bind(norQueue).to(norEx).with(NOR_ROUTING_KEY);
    }

    @Bean
    public Queue dlxQueue() {
        // 创建死信队列
        return QueueBuilder.durable(DLX_QUEUE).build();
    }

    @Bean
    public DirectExchange dlxEx() {
        // 创建死信交换机
        return ExchangeBuilder.directExchange(DLX_EXCHANGE).build();
    }

    @Bean
    public Binding bindingDLX(@Qualifier("dlxQueue") Queue dlxQueue,@Qualifier("dlxEx")DirectExchange dlxEx) {
        // 将死信队列与死信交换机绑定
        return BindingBuilder.bind(dlxQueue).to(dlxEx).with(DLX_ROUTING_KEY);
    }

}

此时在消费者端我们只需要去监听死信队列即可

package com.example.demo.delay;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class Consumer {
    @RabbitListener(queues = DelayQueueConfig.DLX_QUEUE)
    public void delay(Message message) {
        System.out.println("获取到订单," + message.getBody() + "查询数据库是否已支付?未支付则回滚");
    }
}

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

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

相关文章

vscode“检测到 #include 错误,请更新 includepath。”的问题解决办法

目录 一.报错更新includepath​编辑 二.原因 三.解决方法 一.报错更新includepath 如图 二.原因 1.没有安装gcc 2.没有配置好环境 winR打开cmd,输入gcc -v,如果安装了gcc,会返回版本 三.解决方法 1.安装MinGW 2.添加MinGW环境变量 将bin文件夹的位置添加到系统环境变量中…

三分钟搭建个人博客技术栈Nuxt3+vite+mysql+koa2

最近也是想入一下Nuxt3的坑,然后就写了一个博客系统,目前已开源github,欢迎大家star!!! 效果预览 网址:http://180.76.121.2:3000/ github地址 https://github.com/ztzzhi/ztzzhi-nuxt3-vite…

MySQL事物(基础篇)

MySQL事务事物的基本概念事物的ACID属性事务的使用事务隔离级别MVCC&ReadViewMySQL是否还存在幻读事物的基本概念 Transaction作为关系型数据库的核心组成,在数据安全方面有着非常重要的作用,本文会一步步解析事务的核心特性,以获得对事…

多云数据存储,理想与现实之间还差着什么?

去年底,“数据二十条”正式颁布,数据要素全面提速已是指日可待。 无疑,数据作为数字经济的基础,其价值的释放依赖于数据的流动、共享和应用。数据要素只有充分地流动和应用起来,才能够实现价值的最大化。 换而言之&a…

VPN、IPSEC、AH、ESP、IKE、DSVPN

目录 1.什么是数据认证,有什么作用,有哪些实现的技术手段? 2.什么是身份认证,有什么作用,有哪些实现的技术手段? 3.什么VPN技术? 4. VPN技术有哪些分类? 5. IPSEC技术能够提供哪些安全服务? 6. IPSEC的技术架构是什么?…

idea中使用git工具

目录一、IDEA中配置git二、git操作将项目设置成git仓库一、IDEA中配置git 打开idea,点击File–>Settings 点击版本控制,然后点击git 将你的git.exe安装目录填到下面位置 点击test可以看到显示了版本,说明配置成功 二、git操作 将项目设置…

geoserver更换默认的端口、修改默认密码

geoserver默认的端口是8080,有的时候会与其他的项目相冲突,我们的目标是将端口修改为8888,如何更改呢?geoserver正常安装的默认用户名密码为admin/geoserver,如何做一个修改呢将默认密码修改为其他的。 修改端口 分两种情况: (一)如果安装的时候,指定了端口,修改s…

elasticsearch基础教程

elasticsearch安装 有些软件对于安装路径有一定的要求,例如:路径中不能有空格,不能有中文,不能有特殊符号,等等。 为了避免不必要的麻烦,也懒得一一辨别踩坑,我们人为作出「统一的约定」&…

2023_深入学习HTML5

H5 基于html5和 css3和一部分JS API 结合的开发平台(环境) 语义化标签 header : 表示头部,块级元素 footer : 表示底部,块级元素 section :区块 nav : 表示导航链接 aside : 表示侧边栏 output &am…

Flume系列:Flume组件架构

目录 Apache Hadoop生态-目录汇总-持续更新 一:Flume 概述 二:Flume 基础架构 2.1:Agent 2.2:Source 2.3:Sink 2.4:Channel 1) Memory Channel 2) File Channel 3) Kafka Channel 2.5&#xff1a…

AI 绘画 API 超详细使用教程 - 附微信小程序接入代码

写在前面 【AI绘画/AI图像生成】已成为现下炙手可热的话题,AI 大模型训练的成本高昂,算法研究时间周期较长,对于大多数人来说,自研一套算法模型还是非常困难的,因此 AI 绘画 API 就应运而生,直接调用 AI 绘…

MRI图像配准技术及其未来

前言 早在20世纪40年代数字革命开始之前,图像配准就已经成为一个具有重要现实意义的过程。这技术首次应用于彩印,即将几种单色图案叠加在一起形成多色图案。为了生成最终所需的多色印刷品,各个层相对于另一个层的对齐必须是精确的。若个别层…

linux PAM模块简介

PAM模块简介1. 介绍1.1 概念1.2 验证过程简述2. 配置文件介绍2.1 PAM的模块类型2.2 PAM的控制标记2.3 PAM的模块路径3. 验证机制3.1 login的验证机制流程3.2 pam相关文件4. 示例4.1 ssh远程登录控制4.2 禁止账号间使用su命令切换4.3 限制root从tty1,tty2,tty5登录1.…

墨菲安全入选网络安全全景图,将持续深耕软件供应链安全垂直领域

2023年4月7日,中国网络安全领域的专业媒体安全牛正式发布第十版网络安全行业全景图,展现了我国网络安全行业的应用发展与变革创新,所有申请企业通过多个维度审核考量。墨菲安全作为一家专注于软件供应链安全领域的创新企业,以开发…

数据层的解决方案(NOSQL)

1.Redis 1.Redis是一款key-value存储结构的内存结构的内存级NoSQL数据库 支持多种数据存储 支持持久化 支持集群 2.服务器的启动命令&#xff1a; redis-server.exe redis.windows.conf 3.客户端启动命令 redis-cli.exe 4.SpringBoot整合Redis 1.导入相应的依赖 <…

ESP32学习笔记09-ADC多通道采集 dma方式传输

9. ADC多通道采集 dma方式传输 9.1 DIG SAR ADC 控制器 9.1.1特点 高性能。时钟更快,因此采样速率实现了大幅提升。支持多通道扫描模式。每个 SAR ADC 的测量规则可见样式表。扫描模式可配置为 单通道模式双通道模式交替模式。扫描可由软件或 I2S 总线发起。支持 DMA,扫描完…

Win10 安装配置 Hadoop 及 Spark

以下内容只针对 Win10 系统 1. 环境安装 (1) 安装Java并配置环境变量 https://www.oracle.com/java/technologies/downloads/#java8-windows (2) 安装Scala https://www.scala-lang.org/ 或 https://github.com/lampepfl/dotty/releases/tag/3.2.2 配置环境变量&#xff0…

谷歌研究科学家:ChatGPT秘密武器的演进与局限

来源&#xff5c;TalkRL OneFlow编译 翻译&#xff5c;徐佳渝、贾川 同样是基于GPT预训练模型&#xff0c;为什么ChatGPT的效果要远远超出GPT-3等前几代模型&#xff1f;答案已经揭晓&#xff0c;成就ChatGPT的秘密武器在于RLHF&#xff0c;也就是人类反馈的强化学习。 在预训…

SpringMVC的入门案例

三层架构和mvc 三层架构&#xff1a; 我们的开发架构一般都是基于两种形式&#xff0c;一种是C/S 架构&#xff0c;也就是客户端/服务器&#xff0c;另一种是 B/S 架构&#xff0c;也就是测览器服务器。在 avaEE开发中&#xff0c;几乎全都是基于 B/S 架构的开发。那么在 B/S…

Dream 主题之 Halo 2.0 适配,以及适配前后的一些异同

经过一段时间的适配&#xff0c;目前 Dream 已经发布了基于 Halo 2.x 的第一个预发版本。目前对主题所有功能都完成了适配&#xff0c;但是由于 Halo 2.x 与 1.x 的一些不同&#xff0c;以及 Thyeleaf 模板引擎与 FreeMaker 模板渲染引擎的一些不同的特性&#xff0c;适配前与适…