rabbitMQ死信队列快速编写记录
文章目录
- 1.介绍
- 1.1 什么是死信队列
- 1.2 死信队列有什么用
- 2. 如何编码
- 2.1 架构分析
- 2.2 maven坐标
- 2.3 工具类编写
- 2.4 consumer1编写
- 2.5 consumer2编写
- 2.6 producer编写
- 3.整合springboot
- 3.1 架构图
- 3.2 maven坐标
- 3.3 构建配置类,创建exchange,queue,并绑定
- 3.4 编写生产者(controller的一个方法)
- 3.5 编写消费者(一个类, 方法上加上@RabbitListenner,表明需要监听的queue)
- 4. 常见参数汇总
1.介绍
1.1 什么是死信队列
再rabbitMQ中,有两个重要的组件。exchange(交换机),queue(队列)。交换机用于路由消息,简单来说就是接收客户端传递的消息
,转发
到queue中。队列做的事情就是存储消息
。
但消息并不会一只存储在队列中。当存在一下三种情况,消息就会死掉
- 队列存储不了过多的消息
- 消息本身存在过期时间
当遇到死掉的消息时,我们通常会将这些死信
转发到新的交换机中,这个交换机就叫做死信交换机
,而配合死信交换机存储信息的队列,叫做死信队列
1.2 死信队列有什么用
死信队列在构建延迟队列时,有巨大作用
。比如用户购票订单,30min不支付就过期。在rabbitMQ中可以这样实现
- 1 存储购票信息到
exchange-queue
中 - 2 设置消息过期时间为30min
- 3 如果超过30min消息未被消费(消息过期,成为死信),存储死信队列,通知服务取消订单
2. 如何编码
2.1 架构分析
先上绑定架构图
整个流程中,出现了三方。在编写代码时,我们可以分三个大类,分别是producer
,consumer1
,consumer2
。其消息传递顺序如下
producer
-> normal_exchange- normal_queue ->
consumer1
- dead_queue->
consumer2
我们可以在编写consumer1
的时候,完成exchange和queue的创建与绑定
2.2 maven坐标
<dependency><groupId>com.rabbitmq</groupId><artifactId>amqp-client</artifactId><version>5.9.0</version></dependency>
2.3 工具类编写
rabbitMQ整体的编写流程如下
- 创建Connection工厂
- 配置工厂
- 创建链接
- 获取channel
- 通过channel创建exchange, queue, 关系绑定, 监听消息, 发送消息
因此,我们可以先创建工具类,帮我们获取channel,以此减少开发代码量
public class MQUtils {public static Channel getChannel() throws Exception {// 创建工厂链接ConnectionFactory factory = new ConnectionFactory();// 设置工厂factory.setHost("your_ip");factory.setUsername("your_username");factory.setPassword("your_password");factory.setVirtualHost("/"); // 基本都是/Connection connection = factory.newConnection();Channel channel = connection.createChannel();return channel;}
}
2.4 consumer1编写
public class Consumer1 {static String EXCHANGE_NAME = "normal_exchange";static String QUEUE_NAME = "normal_queue";static String DEAD_EXCHANGE_NAME = "dead_exchange";static String DEAD_QUEUE_NAME = "dead_queue";public static void main(String[] args) throws Exception{Channel channel = MQUtils.getChannel();// 普通交换机channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT, false, true, null);// 普通队列// 配置死信交换机参数HashMap<String, Object> map = new HashMap<>();// 配置normal_queue连接的dead_exchangemap.put("x-dead-letter-exchange", DEAD_EXCHANGE_NAME);// 设置normal_queue的消息过期时间map.put("x-message-ttl", 10000);// 设置路由到死信交换机的路由key: lisimap.put("x-dead-letter-routing-key", "lisi");// map.put("x-max-length", 6); // 设置队列最大长度channel.queueDeclare(QUEUE_NAME, false, false, true, map);// 绑定普通交换机和普通队列channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "zhangsan");// 死信交换机channel.exchangeDeclare(DEAD_EXCHANGE_NAME, BuiltinExchangeType.DIRECT, false, true, false, null);// 死信队列channel.queueDeclare(DEAD_QUEUE_NAME, false, false, true, null);// 绑定死信交换机和死信队列channel.queueBind(DEAD_QUEUE_NAME, DEAD_EXCHANGE_NAME, "lisi");// 监听channel.basicConsume(QUEUE_NAME, false, (consumerTag, message) -> {System.out.println("监听普通队列: " + new String(message.getBody()));}, consumerTag -> {});}
}
2.5 consumer2编写
public class Consumer2{static String DEAD_QUEUE_NAME = "dead_queue";public static void main(String[] args) throws Exception{Channel channel = MQUtils.getChannel();// 监听channel.basicConsume(DEAD_QUEUE_NAME, true, (consumerTag, message) -> {System.out.println("监听死信队列: " + new String(message.getBody()));}, consumerTag -> {});}
}
2.6 producer编写
public class Producer {static String EXCHANGE_NAME = "normal_exchange";public static void main(String[] args) throws Exception{Channel channel = MQUtils.getChannel();for (int i = 0; i < 10; i++) {String msg = i + "";channel.basicPublish(EXCHANGE_NAME, "zhangsan",null,msg.getBytes());}}
}
3.整合springboot
3.1 架构图
3.2 maven坐标
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId><version>2.3.9.RELEASE</version></dependency>
3.3 构建配置类,创建exchange,queue,并绑定
package com.xhf.mq.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;@Configuration
public class TTLConfig {/*-----交换机名称-----*/private static final String EXCHANGE_NAME = "X";private static final String DEAD_EXCHANGE_NAME = "Y";/*-----队列名称-----*/private static final String QUEUE_NAME1 = "QA";private static final String QUEUE_NAME2 = "QB";private static final String DEAD_QUEUE_NAME = "QD";// 注册交换机@Bean("xExchange")public DirectExchange xExchange() {return ExchangeBuilder.directExchange(EXCHANGE_NAME).autoDelete().build();
// return new DirectExchange(EXCHANGE_NAME);}// 注册死信交换机@Bean("deadExchange")public DirectExchange deadExchange() {return ExchangeBuilder.directExchange(DEAD_EXCHANGE_NAME).autoDelete().build();}// 注册队列QA@Bean("queueA")public Queue queueA() {return QueueBuilder.nonDurable(QUEUE_NAME1).withArgument("x-message-ttl", 10000).withArgument("x-dead-letter-exchange", DEAD_EXCHANGE_NAME).withArgument("x-dead-letter-routing-key", "YD").build();}// 注册队列QB@Bean("queueB")public Queue queueB() {return QueueBuilder.nonDurable(QUEUE_NAME2).withArgument("x-message-ttl", 40000).withArgument("x-dead-letter-exchange", DEAD_EXCHANGE_NAME).withArgument("x-dead-letter-routing-key", "YD").build();}// 注册队列QD@Bean("queueD")public Queue queueD() {return QueueBuilder.nonDurable(DEAD_QUEUE_NAME).build();}// 绑定普通交换机, 队列@Beanpublic Binding queueABindingX(@Qualifier("queueA") Queue queueA, @Qualifier("xExchange") Exchange xExchange) {return BindingBuilder.bind(queueA).to(xExchange).with("XA").and(null);}@Beanpublic Binding queueBBindingX(@Qualifier("queueB") Queue queueB, @Qualifier("xExchange") Exchange xExchange) {return BindingBuilder.bind(queueB).to(xExchange).with("XB").and(null);}// 绑定死信交换机, 队列@Beanpublic Binding queueDBindingY(@Qualifier("queueD") Queue queueD, @Qualifier("deadExchange") Exchange deadExchange) {return BindingBuilder.bind(queueD).to(deadExchange).with("YD").and(null);}
}
3.4 编写生产者(controller的一个方法)
@GetMapping("/sendToQA")public void sendToQA() {// 向X交换机发送消息, 消息通过"XA"路由到队列rabbitTemplate.convertAndSend("X", "XA", "hello".getBytes());}
3.5 编写消费者(一个类, 方法上加上@RabbitListenner,表明需要监听的queue)
@Component
public class Customer {@RabbitListener(queues = "QD")public void customer(Message message, Channel channel) {byte[] body = message.getBody();System.out.println(new String(body));}
}
4. 常见参数汇总
- x-dead-letter-exchange :死信交换机名称
- x-message-ttl:消息time to live时间(过期时间)
- x-dead-letter-routing-key:死信交换机路由key
- x-max-length:队列最大长度
相关文章:

rabbitMQ死信队列快速编写记录
文章目录 1.介绍1.1 什么是死信队列1.2 死信队列有什么用 2. 如何编码2.1 架构分析2.2 maven坐标2.3 工具类编写2.4 consumer1编写2.5 consumer2编写2.6 producer编写 3.整合springboot3.1 架构图3.2 maven坐标3.3 构建配置类,创建exchange,queue&#x…...
数位dp,338. 计数问题
338. 计数问题 - AcWing题库 给定两个整数 a 和 b,求 a 和 b 之间的所有数字中 0∼90∼9 的出现次数。 例如,a1024,b1032,则 a 和 b 之间共有 9 个数如下: 1024 1025 1026 1027 1028 1029 1030 1031 1032 其中 0 出…...
如何解决git clone http/https仓库失败(403错误)
本来不打算写这篇文章,但是后来又遇到这个问题忘了之前是怎么解决的了。 一般情况下,个人使用 GitHub 等平台时是使用 SSH 协议的,这样不光方便管理可访问用户,也保证了安全性。但是 GitHub 上仓库的 SSH 地址是要登陆才能看到&a…...

华为云云耀云服务器L实例评测 | 实例评测使用之硬件性能评测:华为云云耀云服务器下的硬件运行评测
华为云云耀云服务器L实例评测 | 实例评测使用之硬件性能评测:华为云云耀云服务器下的硬件运行评测 介绍华为云云耀云服务器 华为云云耀云服务器 (目前已经全新升级为 华为云云耀云服务器L实例) 华为云云耀云服务器是什么华为云云耀…...

Elasticsearch:使用 Elasticsearch 进行语义搜索
在数字时代,搜索引擎在通过浏览互联网上的大量可用信息来检索数据方面发挥着重要作用。 此方法涉及用户在搜索栏中输入特定术语或短语,期望搜索引擎返回与这些确切关键字匹配的结果。 虽然关键字搜索对于简化信息检索非常有价值,但它也有其局…...
JVM的主要组成及其作用
jvm主要组成部分有: 类加载器、运行时数据区 (内存结构)、执行引擎、本地接口库、垃圾回收机制 Java程序运行的时候,首先会通过类加载器把Java 代码转换成字节码。然后运行时数据区再将字节码加载到内存中,但字节码文件只是JVM 的一套指令集规范…...

会议AISTATS(Artificial Intelligence and Statistics) Latex模板参考文献引用问题
前言 在看AISTATS2024模板的时候,发现模板里面根本没有教怎么引用,要被气死了。 如下,引用(Cheesman, 1985)的时候,模板是自己手打上去的?而且模板提供的那三个引用,根本也没有Cheesman这个人,…...

2023最新外贸建站:WordPress搭建外贸独立站零基础小白保姆级教程
想从零开始建立一个外贸自建站,那么你来对地方了。 如果你还在找外贸建站或者是WordPress建站教程,不妨看看这篇文章,本教程涵盖了2023最新的外贸建站教程,你将学会使用WordPress自建外贸独立站,步骤包括购买域名主机…...
HTTP请求交互基础(基于GPT3.5,持续更新)
HTTP交互基础 目的HTTP定义详解HTTP协议(规范)1. 主要组成部分1.1 请求行(Request Line):包含请求方法、请求URI(Uniform Resource Identifier)和HTTP协议版本。1.2 请求头部(Reques…...

小谈设计模式(6)—依赖倒转原则
小谈设计模式(6)—依赖倒转原则 专栏介绍专栏地址专栏介绍 依赖倒转原则核心思想关键点分析abc 优缺点分析优点降低模块间的耦合度提高代码的可扩展性便于进行单元测试 缺点增加代码的复杂性需要额外的设计和开发工作 Java代码实现示例分析 总结 专栏介绍…...

JetBrains常用插件
Codota AI Autocomplete Java and JavaScript:自动补全插件 Background Image plus:背景图片设置 rainbow brackets:彩虹括号,便于识别 CodeGlance2: 类似于 Sublime 中的代码缩略图(代码小地图ÿ…...

【C++哈希应用】位图、布隆过滤器
【C哈希应用】位图、布隆过滤器 目录 【C哈希应用】位图、布隆过滤器位图概念位图的实现位图改造位图应用总结布隆过滤器布隆过滤器的提出布隆过滤器的概念布隆过滤器的查找布隆过滤器删除布隆过滤器优点布隆过滤器缺陷 作者:爱写代码的刚子 时间:2023.9…...
Qt 编译纯c的C99的项目, error: undefined reference to `f()‘
把Cpp的后缀该为C是什么样的 尝试引用一个奇门排盘的c程序,在git上找到的叫cqm, 然后总是报错 error: undefined reference to f() 很是郁闷 于是新建了个项目试验一下,终于摸清了需要命名空间。 后来这么写就可以了 a.h namespace XX …...

TensorFlow入门(五、指定GPU运算)
一般情况下,下载的TensorFlow版本如果是GPU版本,在运行过程中TensorFlow能自动检测。如果检测到GPU,TensorFlow会默认利用找到的第一个GPU来执行操作。如果机器上有超过一个可用的GPU,除第一个之外的其他GPU默认是不参与计算的。如果想让TensorFlow使用这些GPU执行操作,需要将运…...

Unity - 实践: Metallic流程贴图 转 Specular流程贴图
文章目录 目的Metallic Flow - SP - 输出输出的 MRA (MGA) 贴图 Metallic->Specular (根据教程一步一步实践)1. Base color Metallic -> Diffuse2. Base color Metallic -> Specular3. Roughness -> Glossiness输出贴图,在 unity 中展示:M…...
第三章:最新版零基础学习 PYTHON 教程(第四节 - Python 运算符—Python 逻辑运算符及示例)
运算符用于对值和变量执行操作。这些是执行算术和逻辑计算的特殊符号。运算符运算的值称为操作数。 表中的内容逻辑运算符 逻辑与运算符 逻辑或运算符 逻辑非运算符 逻辑运算符的求值顺序 逻辑运算符 在 Python 中,逻辑运算符用于条件语句(True 或 False)。它们执行逻辑 AN…...
如何做好测试?(三)功能测试 (Functional Testing, FT)
1. 功能测试的详细介绍: 功能测试 (Functional Testing, FT),是一种软件测试方法,旨在验证系统的功能是否按照需求规格说明书或用户期望的方式正常工作。它关注系统的整体行为,以确保各个功能模块和组件之间的交互和集成正确。 …...
Ubuntu-Server-22.04安装桌面+VNC
前提:Ubuntu Server安装好后,ubantu其他版本是否适用这里未知,欢迎大佬们前来评论 一、默认没有图形界面,有时觉得用图形界面操作更简单直接,于是用如下命令安装: 1.更新本地环境 sudo apt-get update s…...

职业规划,什么是职业兴趣 - 我喜欢做什么?
能够在工作岗位上面做出成绩的人,都是结合自身兴趣,对职业进行合理规划的那一类。尤其是步入中年以后,能够创造出巨大价值的人,无一例外都是喜欢自己职业的人。没有将兴趣融入工作的人,只能够忍受默默无闻地活着&#…...

基于Java的高校学生党员发展流程管理系统设计与实现(源码+lw+部署文档+讲解等)
文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序(小蔡coding)有保障的售后福利 代码参考源码获取 前言 💗博主介绍:✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

给网站添加live2d看板娘
给网站添加live2d看板娘 参考文献: stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下,文章也主…...

如何应对敏捷转型中的团队阻力
应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中,明确沟通敏捷转型目的尤为关键,团队成员只有清晰理解转型背后的原因和利益,才能降低对变化的…...

从零开始了解数据采集(二十八)——制造业数字孪生
近年来,我国的工业领域正经历一场前所未有的数字化变革,从“双碳目标”到工业互联网平台的推广,国家政策和市场需求共同推动了制造业的升级。在这场变革中,数字孪生技术成为备受关注的关键工具,它不仅让企业“看见”设…...

基于单片机的宠物屋智能系统设计与实现(论文+源码)
本设计基于单片机的宠物屋智能系统核心是实现对宠物生活环境及状态的智能管理。系统以单片机为中枢,连接红外测温传感器,可实时精准捕捉宠物体温变化,以便及时发现健康异常;水位检测传感器时刻监测饮用水余量,防止宠物…...