消息队列RabbitMQ.03.死信交换机的讲解与使用
目录
一、死信队列(延迟队列) 概念讲解
二、确认消息(局部方法处理消息)
三、代码实战
1.编写生产者代码,配置消息、直连交换机、路由键
1.1代码解析:
2.配置消费者接受类接受直连交换机的路由键
2.1. String msg,Channel channel ,@Header(AmqpHeaders.DELIVERY_TAG) ,long tag 方法参数解析:
2.2.channel.basicAck(tag,true); 代码解析
2.3.channel.basicReject(tag,true); 代码解析:
3.对死信交换机进行测试
一、死信队列(延迟队列) 概念讲解
- 消息 TTL 过期
- 队列满了,无法再次添加数据
- 消息被拒绝(reject 或 nack),并且 requeue =false
二、确认消息(局部方法处理消息)
默认情况下消息消费者是自动 ack (确认)消息的,如果要手动 ack(确认)则需要修改确认模式为 manual
spring:rabbitmq:listener:simple:acknowledge-mode: manual
三、代码实战
1.编写生产者代码,配置消息、直连交换机、路由键
@Beanpublic Queue queueA() {//正常Map<String, Object> config = new HashMap<>();//message在该队列queue的存活时间最大为10秒config.put("x-message-ttl", 10000);//x-dead-letter-exchange参数是设置该队列的死信交换器(DLX)config.put("x-dead-letter-exchange", "ExchangeB");//x-dead-letter-routing-key参数是给这个DLX指定路由键config.put("x-dead-letter-routing-key", "bb");return new Queue("queueA",true,false,false,config);}@Beanpublic DirectExchange ExchangeA(){return new DirectExchange("ExchangeA");}@Beanpublic Binding bindingA(){return BindingBuilder.bind(queueA()).to(ExchangeA()).with("aa");}@Beanpublic Queue queueB() {return new Queue("queueB");}@Beanpublic DirectExchange ExchangeB(){return new DirectExchange("ExchangeB");}@Beanpublic Binding bindingB(){return BindingBuilder.bind(queueB()).to(ExchangeB()).with("bb");}
1.1代码解析:
Map<String, Object> config = new HashMap<>();
//message在该队列queue的存活时间最大为10秒
config.put("x-message-ttl", 10000);
//x-dead-letter-exchange参数是设置该队列的死信交换器(DLX)
config.put("x-dead-letter-exchange", "ExchangeB");
//x-dead-letter-routing-key参数是给这个DLX指定路由键
config.put("x-dead-letter-routing-key", "bb");
return new Queue("queueA",true,false,false,config);
首先我们需要知道死信产生的原因:
- 消息过期: 消息在队列中等待的时间超过了指定的过期时间。
- 消息被拒绝: 消费者拒绝消费消息,并且消息被标记为不可重新投递。
- 队列满: 队列达到最大容量,无法再接收新的消息。
上述代码的作用是让消息等待10秒,如果10秒内没有进入消费者或者没有被操作那么它就会进入死信;我们就会将它放入消息B也就是当作死信就行处理。
return new Queue("queueA",true,false,false,config); 中参数的作用:
true: 持久化,表示队列在消息代理(例如 RabbitMQ)重启后仍然存在。false: 非独占,表示该队列不会被其他连接独占使用。false: 不自动删除,表示即使没有消费者连接,队列也不会被自动删除。config: 包含了上述配置的Map对象,将这些配置应用到队列上。
总体来说,这段代码创建了一个具有消息过期和死信队列功能的队列 "queueA",并配置了过期消息发送到名为 "ExchangeB" 的交换器,并指定了死信的路由键为 "bb"。这样的配置在处理消息的时候能够更加灵活,并且对于消息的生命周期有了额外的控制。
2.配置消费者接受类接受直连交换机的路由键
queueA
@Component
@SuppressWarnings("all")
@Slf4j
@RabbitListener(queues = "queueA")
public class ReceiverQA {@RabbitHandler//手动确认消息public void process(String msg, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws Exception{log.warn("QA接收到:" + msg);//channel.basicAck(tag,true);//拒绝 ture是否重新入队 会一直 循环 false 会直接变成死信channel.basicReject(tag,true);Thread.sleep(1000);}
}
2.1. String msg,Channel channel ,@Header(AmqpHeaders.DELIVERY_TAG) ,long tag 方法参数解析:
Channel channel:
Channel对象表示与消息代理(例如 RabbitMQ)建立的通信通道。该通道提供了与消息代理进行交互的方法,如确认消息、拒绝消息等。在这个方法中,channel参数用于与消息代理进行通信。
@Header(AmqpHeaders.DELIVERY_TAG) long tag:
@Header注解用于提取消息头中的信息。在这里,通过AmqpHeaders.DELIVERY_TAG提取了消息的传送标签(delivery tag)。long tag表示消息的唯一标识符。它是一个标识消息的数字,通常在消息代理传递消息给消费者时分配。这个标识符可以用于在确认、拒绝或重新排队消息时指定特定的消息。
总体来说,这个方法是一个消息处理方法,其中
message参数表示消息的内容,channel参数用于与消息代理进行通信,而tag参数表示消息的唯一标识符,用于在消息确认、拒绝等操作中指定特定的消息。这样的方法通常用于处理从消息队列中接收到的消息。
2.2.channel.basicAck(tag,true); 代码解析
channel.basicAck(tag,true); 用于确认(acknowledge)消息的方法,通常在消费者成功处理消息后调用。以下是该方法的作用和参数含义:
channel:
- 这是表示与消息代理建立的通信通道的对象。在很多消息队列系统中,通常通过该通道进行消息的发布、消费等操作。
basicAck:
- 这是确认消息的方法。它告诉消息代理,消费者已经成功处理了某个特定的消息。
tag:
- 这是消息的唯一标识符或者句柄。在消费者接收到消息时,消息会被分配一个唯一的标识符,这个标识符用于确认或拒绝特定的消息。
true:
- 这是一个布尔值,通常表示确认多个消息。如果设置为
true,则表示确认到指定tag及其之前的所有消息。如果设置为false,则仅确认指定的消息。
2.3.channel.basicReject(tag,true); 代码解析:
channel.basicReject(tag,true);是在使用 AMQP(Advanced Message Queuing Protocol)中的通道(channel)对象时,用于拒绝一条消息的方法。让我们解释这个方法及其参数的意义:
tag参数:
tag表示消息的唯一标识符,通常是通过消费者获取的消息标签。它用于标识要拒绝的特定消息。
multiple参数:
multiple是一个布尔值,用于指定是拒绝单个消息还是多个消息。如果multiple为false,则表示仅拒绝标记为tag的单个消息。如果multiple为true,则表示拒绝所有比tag小的、未被确认的消息。在这里,true表示拒绝所有比tag小的未确认消息。作用:
channel.basicReject(tag, true)的作用是拒绝一条或多条消息。当消费者无法处理接收到的消息时,可以使用该方法将消息标记为拒绝,并根据需要将其重新排队或进入死信队列。通过将
multiple设置为true,可以一次性拒绝多条消息,这对于批量处理消息的情况很有用。拒绝消息会触发相应的处理机制,例如将消息重新排队或将其发送到死信交换器,具体取决于消息代理的配置。
总体来说,
channel.basicReject(tag, true)是用于拒绝一条或多条消息的方法,其中tag表示消息的标签,而multiple决定了是拒绝单个消息还是多个消息。
queueB
@Component
@SuppressWarnings("all")
@Slf4j
@RabbitListener(queues = "queueB")
public class ReceiverQB {@RabbitHandlerpublic void process(String msg) {log.warn("QB接收到:" + msg);//去数据库做修改//更改数据库的订单状态为取消//update order set status=-1 where id=#{id} and status=1}
}
3.对死信交换机进行测试
@RequestMapping("/send6")public String send6(){template.convertAndSend("ExchangeA","aa","43249849234");return "🤣";}
最后页面网址访问方法/send6即可
相关文章:
消息队列RabbitMQ.03.死信交换机的讲解与使用
目录 一、死信队列(延迟队列) 概念讲解 二、确认消息(局部方法处理消息) 三、代码实战 1.编写生产者代码,配置消息、直连交换机、路由键 1.1代码解析: 2.配置消费者接受类接受直连交换机的路由键 2.1. String msgÿ…...
人工智能原理实验4(2)——贝叶斯、决策求解汽车评估数据集
🧡🧡实验内容🧡🧡 汽车数据集 车子具有 buying,maint,doors,persons,lug_boot and safety六种属性,而车子的好坏分为uncc,ucc,good and vgood四种。 🧡🧡贝叶斯求解🧡🧡…...
算力网络:未来计算资源的驱动力
文章目录 前言一、算力网络的基本概况(一)算力网络的基本概念(二)算力网络研究进展二、运营商的算力网络架构(一)算力网络基础设施构成(二)算力网络编排管理(三)能力开放三、算力网络的优势(一)弹性计算(二)降低成本(三)去中心化四、算力网络的应用场景(一)人…...
java动态导入excel按照表头生成数据库表
1、创建接口接收文件 //controller层 PostMapping("/importExcel1")public void importExcel1(HttpServletRequest request, MultipartFile file) {try {waterMeterService.importExcel1(request,file);} catch (Exception e) {throw new RuntimeException(e);}}//se…...
Java 集合List相关面试题
📕作者简介: 过去日记,致力于Java、GoLang,Rust等多种编程语言,热爱技术,喜欢游戏的博主。 📗本文收录于java面试题系列,大家有兴趣的可以看一看 📘相关专栏Rust初阶教程、go语言基…...
k8s-基础知识(Pod,Deployment,ReplicaSet)
k8s职责 自动化容器部署和复制随时扩展或收缩容器容器分组group,并且提供容器间的负载均衡实时监控,即时故障发现,自动替换 k8s概念及架构 pod pod是容器的容器,可以包含多个container pod是k8s最小可部署单元,容器…...
matlab查看源代码
matlab函数源代码-查看 CtrlD 最简单方便的一种方法,鼠标划中函数名,按CTRLD即可打开函数的m文件...
【数据库学习】PostgreSQL优化
1,思路 2,执行计划 explain sql语句; #查看执行计划。也可以使用navicat的解释功能查看。结果说明: QUERY PLAN Index Scan using tenk1_unique1 on tenk1 (cost0.00..10.01 rows1 width244) --Index 使用索引 --cost&#x…...
微信小程序分页加载功能,结合后端实现上拉底部加载下一页数据,数据加载中和暂无数据提示
🤵 作者:coderYYY 🧑 个人简介:前端程序媛,目前主攻web前端,后端辅助,其他技术知识也会偶尔分享🍀欢迎和我一起交流!🚀(评论和私信一般会回&#…...
idea 打包跳过测试
IDEA操作 点击蓝色的小球 手动命令 mvn clean package -Dmaven.test.skiptrue...
python sqlite3 线程池封装
1. 封装 sqlite3 1.1. 依赖包引入 # -*- coding: utf-8 -*- #import os import sys import datetime import loggingimport sqlite31.2. 封装类 class SqliteTool(object):#def __init__(self, host, port, user, password, database):def __init__(self, host, database):s…...
亚马逊运营:如何通过自养号测评有效防关联,避免砍单
店铺安全对于跨境电商卖家至关重要,它是我们业务稳定运营的基础。一旦店铺遭到亚马逊的封禁,往往意味着巨大的损失。因此,合规运营已经成为了卖家们的共识。然而,许多卖家可能会因为一些看似微小的失误,导致店铺被关联…...
winfrom图像加速渲染时图像不显示
winform中加入这段代码,即使不调用也会起作用;当图像不显示时,可以注释掉这段代码...
Redash 默认key漏洞(CVE-2021-41192)复现
Redash是以色列Redash公司的一套数据整合分析解决方案。该产品支持数据整合、数据可视化、查询编辑和数据共享等。 Redash 10.0.0及之前版本存在安全漏洞,攻击者可利用该漏洞来使用已知的默认值伪造会话。 1.漏洞级别 中危 2.漏洞搜索 fofa "redash"…...
Git学习笔记:3 git tag命令
文章目录 git tag 基本用法1. 创建标签2. 查看标签3. 删除标签4. 推送标签到远程仓库5. 检出标签 普通提交和标签的区别1. 提交(Commit)2. 标签(Tag) git tag 基本用法 git tag 是 Git 中用于管理和操作标签(tag&…...
10年软件测试经验,该有什么新的职业规划?
个人觉得,最关键是识别个人的兴趣和长期目标,以及市场需求,制定符合自己职业发展的规划,列了几个常见的方向: 1. 技术深化 专业领域专长:在某一测试领域(如自动化测试、性能测试、安全测试等&am…...
重构改善既有代码的设计-学习(四):简化条件逻辑
1、分解条件表达式(Decompose Conditional) 可以将大块代码分解为多个独立的函数,根据每个小块代码的用途,为分解而得的新函数命名。对于条件逻辑,将每个分支条件分解成新函数还可以带来更多好处:可以突出条…...
【代码---利用一个小程序,读取文件夹中图片,将其合成为一个视频】
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言程序详细说明总结 前言 提示:这里可以添加本文要记录的大概内容: 创建一个程序将图像合成为视频通常需要使用图像处理和视频编码库。 …...
MVC 和 MVVM的区别
MVC: M(model数据)、V(view视图),C(controlle控制器) 缺点是前后端无法独立开发,必须等后端接口做好了才可以往下走; 前端没有自己的数据中心,太…...
redis—Set集合
目录 前言 1.常见命令 2.使用场景 前言 集合类型也是保存多个字符串类型的元素的,但和列表类型不同的是,集合中1)元素之间是无序的2)元素不允许重复,如图2-24所示。一个集合中最多可以存储22 - 1个元素。Redis 除了支持集合内的增删查改操…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...
k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...
企业如何增强终端安全?
在数字化转型加速的今天,企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机,到工厂里的物联网设备、智能传感器,这些终端构成了企业与外部世界连接的 “神经末梢”。然而,随着远程办公的常态化和设备接入的爆炸式…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
【从零学习JVM|第三篇】类的生命周期(高频面试题)
前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 …...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...
计算机基础知识解析:从应用到架构的全面拆解
目录 前言 1、 计算机的应用领域:无处不在的数字助手 2、 计算机的进化史:从算盘到量子计算 3、计算机的分类:不止 “台式机和笔记本” 4、计算机的组件:硬件与软件的协同 4.1 硬件:五大核心部件 4.2 软件&#…...
HubSpot推出与ChatGPT的深度集成引发兴奋与担忧
上周三,HubSpot宣布已构建与ChatGPT的深度集成,这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋,但同时也存在一些关于数据安全的担忧。 许多网络声音声称,这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...
LangFlow技术架构分析
🔧 LangFlow 的可视化技术栈 前端节点编辑器 底层框架:基于 (一个现代化的 React 节点绘图库) 功能: 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...
