RabbitMQ“延时队列“

1.RabbitMQ"延时队列"

延迟队列存储的对象是对应的延迟消息,所谓“延迟消息”是指当消息被发送以后,并不想让消费者立刻拿到消息,而是等待特定时间后,消费者才能拿到这个消息进行消费
注意RabbitMQ并没有延时队列慨念,其实是通过死信实现
应用场景:订单30分钟未支付取消…

2.整合springboot

创建springboot Maven项目,其pom文件内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.4.2</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.hong</groupId><artifactId>springboot-rabbitmq</artifactId><version>0.0.1-SNAPSHOT</version><name>springboot-rabbitmq</name><description>springboot整合Rabbitmq</description><properties><java.version>17</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><!--RabbitMQ 依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.47</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.24</version></dependency><!--swagger--><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>3.0.0</version></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>3.0.0</version></dependency><!--RabbitMQ 测试依赖--><dependency><groupId>org.springframework.amqp</groupId><artifactId>spring-rabbit-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.4.2</version></plugin></plugins></build></project>

3.配置文件application.properties

spring.rabbitmq.host=10.211.55.4
spring.rabbitmq.port=5672
spring.rabbitmq.username=admin
spring.rabbitmq.password=123456

4.添加Swagger配置类

package com.hong.springboot.rabbitmq.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;/*** @Description: Swagger配置类* @Author: hong* @Date: 2024-01-24 10:38* @Version: 1.0**/
@Configuration
@EnableSwagger2
public class SwaggerConfig {@Beanpublic Docket webApiConfig() {return new Docket(DocumentationType.SWAGGER_2).groupName("webApi").apiInfo(webApiInfo()).select().build();}private ApiInfo webApiInfo() {return new ApiInfoBuilder().title("rabbitmq接口文档").description("本文档描述了 rabbitmq 微服务接口定义").version("1.0").contact(new Contact("JAVA小生不才", "https://blog.csdn.net/qq_41596346?spm=1011.2423.3001.5343", "hst1406959716@163.com")).build();}
}

5.队列TTL配置列

在这里插入图片描述

package com.hong.springboot.rabbitmq.config;import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.HashMap;
import java.util.Map;/*** @Description: TTL队列配置类* @Author: hong* @Date: 2024-01-24 09:57* @Version: 1.0**/@Configuration
public class TTLQueeueConfig {public static final String X_EXCHANGE = "X";public static final String QUEUE_A = "QUEUE_A";public static final String QUEUE_B = "QUEUE_B";//死信交换机public static final String Y_DEAD_LETTER_EXCHANGE = "Y";//死信队列public static final String DEAD_LETTER_QUEUE = "QD";// 声明 xExchange@Bean("xExchange")public DirectExchange xExchange() {return new DirectExchange(X_EXCHANGE);}// 声明 死信队列交换机@Bean("yExchange")public DirectExchange yExchange() {return new DirectExchange(Y_DEAD_LETTER_EXCHANGE);}//声明队列 A ttl 为 10s 并绑定到对应的死信交换机@Bean("queueA")public Queue queueA() {Map<String, Object> args = new HashMap<>(3);//声明当前队列绑定的死信交换机args.put("x-dead-letter-exchange", Y_DEAD_LETTER_EXCHANGE);//声明当前队列的死信路由 keyargs.put("x-dead-letter-routing-key", "YD");//声明队列的 TTLargs.put("x-message-ttl", 10000);return QueueBuilder.durable(QUEUE_A).withArguments(args).build();}// 声明队列 A 绑定 X 交换机@Beanpublic Binding queueaBindingX(@Qualifier("queueA") Queue queueA,@Qualifier("xExchange") DirectExchange xExchange) {return BindingBuilder.bind(queueA).to(xExchange).with("XA");}//声明队列 B ttl 为 40s 并绑定到对应的死信交换机@Bean("queueB")public Queue queueB() {Map<String, Object> args = new HashMap<>(3);//声明当前队列绑定的死信交换机args.put("x-dead-letter-exchange", Y_DEAD_LETTER_EXCHANGE);//声明当前队列的死信路由 keyargs.put("x-dead-letter-routing-key", "YD");//声明队列的 TTLargs.put("x-message-ttl", 40000);return QueueBuilder.durable(QUEUE_B).withArguments(args).build();}//声明死信队列 QD@Bean("queueD")public Queue queueD() {return new Queue(DEAD_LETTER_QUEUE);}//声明队列 B 绑定 X 交换机@Beanpublic Binding queuebBindingX(@Qualifier("queueB") Queue queueB,@Qualifier("xExchange") DirectExchange xExchange) {return BindingBuilder.bind(queueB).to(xExchange).with("XB");}//声明死信队列 QD 绑定关系@Beanpublic Binding deadLetterBindingQAD(@Qualifier("queueD") Queue queueD,@Qualifier("yExchange") DirectExchange yExchange) {return BindingBuilder.bind(queueD).to(yExchange).with("YD");}
}

6.消息生产者

package com.hong.springboot.rabbitmq.controller;import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.text.SimpleDateFormat;
import java.util.Date;/*** @Description: 消息生产者* @Author: hong* @Date: 2024-01-28 10:15* @Version: 1.0**/
@Slf4j
@RequestMapping("ttl")
@RestController
public class SendMessageController {@Autowiredprivate RabbitTemplate rabbitTemplate;@GetMapping("sendMsg/{message}")public void sendMsg(@PathVariable String message) {log.info("当前时间:{},发送一条信息给两个 TTL 队列:{}",new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) , message);rabbitTemplate.convertAndSend("X", "XA", "消息来自ttl为10S的QA队列: " + message);rabbitTemplate.convertAndSend("X", "XB", "消息来自ttl为10S的QB队列: " + message);}
}

7.消息消费者代码

package com.hong.springboot.rabbitmq.consumer;import com.hong.springboot.rabbitmq.config.TTLQueeueConfig;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;import java.text.SimpleDateFormat;
import java.util.Date;/*** @Description: 死信消费者* @Author: hong* @Date: 2024-01-28 10:22* @Version: 1.0**/
@Slf4j
@Component
public class DeadLetterQueueConsumer {@RabbitListener(queues = "QD")public void receiveD(Message message, Channel channel) {String msg = new String(message.getBody());log.info("当前时间:{},收到死信队列信息{}",new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) , msg);}}

启动项目,发起http://localhost:8080/ttl/sendMsg/JAVA%E5%B0%8F%E7%94%9F%E4%B8%8D%E6%89%8D请求
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

8.代码优化

QA和QB的ttl都写死啦,若是再来1个时间不同的咋处理

8.1.TTLQueeueConfig优化

代码中添加如下代码

    //QC 不设置ttl  消息自带ttlpublic static final String QUEUE_C = "QC";//声明队列 C 死信交换机    @Bean("queueC")public Queue queueC() {Map<String, Object> args = new HashMap<>(3);//声明当前队列绑定的死信交换机args.put("x-dead-letter-exchange", Y_DEAD_LETTER_EXCHANGE);//声明当前队列的死信路由 keyargs.put("x-dead-letter-routing-key", "YD");//没有声明 TTL 属性return QueueBuilder.durable(QUEUE_C).withArguments(args).build();}//声明队列C绑定 X 交换机@Beanpublic Binding queueCBindingX(@Qualifier("queueC") Queue queueC,@Qualifier("xExchange") DirectExchange xExchange) {return BindingBuilder.bind(queueC).to(xExchange).with("XC");}

8.2.生产者代码优化

添加如下方法

    /*** 延时队列优化* @param message 消息* @param ttlTime 延时的毫秒*/@GetMapping("sendExpirationMsg/{message}/{ttlTime}")public void sendMsg(@PathVariable String message, @PathVariable String ttlTime) {rabbitTemplate.convertAndSend("X", "XC", message, correlationData -> {correlationData.getMessageProperties().setExpiration(ttlTime);return correlationData;});log.info("当前时间:{},发送一条时长{}毫秒TTL信息给队列C:{}", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) , ttlTime, message);}

在这里插入图片描述

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

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

相关文章

OpenCV-29 自适应阈值二值化

一、引入 在前面的部分我们使用的是全局阈值&#xff0c;整幅图像采用同一个数作为阈值。当时这种方法并不适应于所有情况。尤其是当同一幅图像上的不同部分具有不同的亮度时。这种情况下我们需要采用自适应阈值。此时的阈值时根据图像上的每一个小区域计算与其对应的阈值。因此…

【幻兽帕鲁】开服务器,高性能高带宽(100mbps),免费!!!【学生党强推】

【幻兽帕鲁】开服务器&#xff0c;高性能高带宽&#xff08;100mbps&#xff09;&#xff0c;免费&#xff01;&#xff01;&#xff01;【学生党强推】 教程相关视频地址&#xff1a;https://www.bilibili.com/video/BV16e411Y7Fd/ 目前幻兽帕鲁开服务器有以下几套比较性价比的…

研发日记,Matlab/Simulink避坑指南(九)——可变数组应用Bug

文章目录 前言 背景介绍 问题描述 分析排查 解决方案 总结归纳 前言 见《研发日记&#xff0c;Matlab/Simulink避坑指南(四)——transpose()转置函数Bug》 见《研发日记&#xff0c;Matlab/Simulink避坑指南(五)——CAN解包 DLC Bug》 见《研发日记&#xff0c;Matlab/Si…

qemu + vscode图形化调试linux kernel

一、背景 使用命令行连接gdb 在调试时&#xff0c;虽然可以通过tui enable 显示源码&#xff0c;但还是存在设置断点麻烦&#xff08;需要对着源码设置&#xff09;&#xff0c;terminal显示代码不方便&#xff0c;不利于我们学习&#xff1b;另外在gdb 下p命令显示结构体内容…

重构改善既有代码的设计-学习(六):处理继承关系

1、函数上移&#xff08;Pull Up Method&#xff09; 无论何时&#xff0c;只要系统内出现重复&#xff0c;你就会面临“修改其中一个却未能修改另一个”的风险。通常&#xff0c;找出重复也有一定的难度。 所以&#xff0c;某个函数在各个子类中的函数体都相同&#xff08;它们…

Pandas--数据结构 - Series(3)

Pandas Series 类似表格中的一个列&#xff08;column&#xff09;&#xff0c;类似于一维数组&#xff0c;可以保存任何数据类型。 Series 特点&#xff1a; 索引&#xff1a; 每个 Series 都有一个索引&#xff0c;它可以是整数、字符串、日期等类型。如果没有显式指定索引&…

Android Automotive:在路上释放 Android 操作系统的力量

Android Automotive&#xff1a;在路上释放 Android 操作系统的力量 Android 在汽车行业的历程车载信息娱乐系统 (IVI) 的演变汽车中的 Android&#xff1a;演变和进步Android 汽车操作系统的崛起Polestar 2&#xff1a;开创 Android 汽车体验Android 开源项目 (AOSP) 及其他项…

华为三层交换机与防火墙对接配置上网示例

三层交换机与防火墙对接上网配置示例 组网图形 图1 三层交换机与防火墙对接上网组网图 三层交换机简介配置注意事项组网需求配置思路操作步骤配置文件 三层交换机简介 三层交换机是具有路由功能的交换机&#xff0c;由于路由属于OSI模型中第三层网络层的功能&#xff0c;所以…

mac安装mysql的8.0设置面板启动不了

1、前言 记得之前安装mysql5.7的时候&#xff0c;是可以直接从设置里面的mysql面板启动的&#xff0c;但是到了mysql8.0之后就启动不了了&#xff0c;这个问题不知道是版本问题还是我换了m系列芯片的mysql导致的&#xff0c;之前很多次都启动不了&#xff0c;这次搞了下&#x…

力扣20、有效的括号(简单)

1 题目描述 图1 题目描述 2 题目解读 给定的字符串只包含括号&#xff0c;判断这个字符串中的括号是否按照正确顺序出现&#xff0c;即这个字符串是否有效。 3 解法一&#xff1a;栈 C的STL中的stack&#xff0c;在解题时非常好用。 3.1 解题思路 使用栈stk&#xff0c;并枚举…

Windows 和 Anolis 通过 Docker 安装 Milvus 2.3.4

Windows 10 通过 Docker 安装 Milvus 2.3.4 一.Windows 安装 Docker二.Milvus 下载1.下载2.安装1.Windows 下安装&#xff08;指定好Docker文件目录&#xff09;2.Anolis下安装 三.数据库访问1.ATTU 客户端下载 一.Windows 安装 Docker Docker 下载 双击安装即可&#xff0c;安…

移动Web——平面转换-多重转换

1、平面转换-多重转换 多重转换技巧&#xff1a;先平移再旋转 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content"IEedge" /><meta name&qu…

Hive中left join 中的where 和 on的区别

目录 一、知识点 二、测试验证 三、引申 一、知识点 left join中关于where和on条件的知识点&#xff1a; 多表left join 是会生成一张临时表。on后面&#xff1a; 一般是对left join 的右表进行条件过滤&#xff0c;会返回左表中的所有行&#xff0c;而右表中没有匹配上的数…

C++11(中):智能指针

智能指针 1.内存泄漏1.1内存泄漏的概念以及危害1.2内存泄漏的场景1.3如何避免内存泄漏 2.智能指针的使用及原理2.1RAII2.2智能指针的原理2.3 std::auto_ptr2.4 定制删除器2.5 std::unique_ptr2.6 std::shared_ptr2.7 std::weak_ptr2.7.1 std::shared_ptr的循环引用2.7.2 循环引…

qemu 单步调试linux driver

一、背景 qemu单步调试arm64 linux kernel-CSDN博客介绍了如何单步调试kernel&#xff0c; 但是我们经常写一些测试driver, driver的部分如何调试&#xff1f; 二、环境准备 调试driver 就需要准备一个简单的driver&#xff0c; 这里用最简单的hello world来演示如何调试&am…

java日志框架总结(三 、Log4j日志框架)

一、简介 Log4j ( Logger For Java ) , Java 日志的记录包。 官方网站 。Log4j 是 Apache 的一个开源项目&#xff0c; 为Java提供了日志记录功能。能够让程序员非常方便的记录日志&#xff0c; 并且提供了多种适配方式&#xff0c;能满足各种需求。 使用Log4j 只需要导入一个…

【设计模式】腾讯面经:原型模式怎么理解?

什么是原型模式&#xff1f; 设计模式是编程世界的基石&#xff0c;其中原型模式无疑是一种常用而又高效的创建对象的手段。那么&#xff0c;什么是原型模式呢&#xff1f;又该如何去实现它&#xff1f; 在软件工程中&#xff0c;原型模式是一种创建型设计模式。我们可以这样…

2024獬豸杯完整Writeup

文章目录 手机手机基本信息- 1、IOS手机备份包是什么时候开始备份的。&#xff08;标准格式&#xff1a;2024-01-20.12:12:12)手机基本信息- 2、请分析&#xff0c;该手机共下载了几款即时通讯工具。&#xff08;标准格式&#xff1a;阿拉伯数字&#xff09;手机基本信息- 3、手…

Zerosync:构建基于STARK的Bitcoin证明系统

1. 引言 前序博客&#xff1a; BitcoinSTARK: ZeroSync & Khepri Robin Linus、Tino Steffens、Lukas George 等人成立了一个名为 ZeroSync 协会&#xff08;ZeroSync Association&#xff09;的瑞士非营利组织&#xff0c;该组织将牵头开发比特币证明系统。ZeroSync 于…

共享自助空间打破传统束缚,创新消费体验

共享自助空间是指将传统的办公空间、工作空间、社交空间等资源进行共享&#xff0c;为个体或小型团体提供灵活的使用服务和自主管理的空间。这种模式使得个人可以在一个共享的环境中独立办公、工作或社交&#xff0c;并能享受到共享资源和服务的便利&#xff0c;比如共享茶室、…