036 RabbitMQ消息确认 死信队列 延时队列

文章目录

  • 生产者确认模式
    • application.properties
    • MessageController.java
    • MessageConfirmRallback.java
  • 生产者回退模式
    • application.properties
    • MessageConfirmRallback.java
    • MessageController.java
  • 消费者手动确认
    • application.properties
    • ConsumerAckQueueListener.java
  • 死信队列
  • 延时队列

测试链接 http://localhost:8080/direct/sendMsg?exchange=order_exchange&routingKey=order.A&msg=aaa

思考问题: 生产者能百分之百将消息发送给消息队列吗?
不确定的
1.生产者如果发消息给MQ,消息在传输的过程中可能丢失。找不到交换机
2.交换机路由到队列,也存在丢失消息的可能性

问题解决方案:
1.生产者确认模式
2.生产者回退模式

目标: 演示生产者确认的效果,消息百分百进入交换机
实现步骤:
1.配置开启生产者确认模式
2.编写生产者确认回调方法,处理业务逻辑
3.在RabbitMQ模板对象中,设置回调逻辑
4.测试请求一下
目标2: 消息能够从交换机百分百进入到队列
实现步骤:
1.配置开启生产者回退模式
2.编写生产者回退的回调方法
3.设置回退回调方法
4.测试

生产者确认模式

application.properties

# 配置开启生产者确认模式
spring.rabbitmq.publisher-confirms=true

MessageController.java

package com.cubemall.controller;/*
目标: 搭建RabbitMQ高级特性演示环境
1.搭建消费者工程[复用之前工程]
2.搭建提供者工程[复用之前工程]
3.编写MessageController: 用来发送消息
交换机
路由键
消息内容
4.RabbitMQ配置交换机和队列,及路由键
5.编写消费者监听思考问题: 生产者能百分之百将消息发送给消息队列吗?
不确定的
1.生产者如果发消息给MQ,消息在传输的过程中可能丢失。找不到交换机
2.交换机路由到队列,也存在丢失消息的可能性问题解决方案:
1.生产者确认模式
2.生产者回退模式目标: 演示生产者确认的效果,消息百分百进入交换机
实现步骤:
1.配置开启生产者确认模式
2.编写生产者确认回调方法,处理业务逻辑
3.在RabbitMQ模板对象中,设置回调逻辑
4.测试请求一下*/import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class MessageController {//发送消息接口@Autowiredprivate RabbitTemplate rabbitTemplate;//定义发送消息的接口@RequestMapping("/direct/sendMsg")public String sendMsgtoMQ(String exchange,String routingKey,String msg){rabbitTemplate.convertAndSend(exchange,routingKey,msg);return "已投递";}
}

MessageConfirmRallback.java

package com.cubemall.controller;import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;/*
发送消息回调确认类:消息如果没有进入交换机,会回调当前类中的confirm*/
@Component
public class MessageConfirmRallback implements RabbitTemplate.ConfirmCallback {//配置回调的方法@Autowiredprivate RabbitTemplate rabbitTemplate;//配置在当前对象注入之后,再设置当前对象到RabbitTemplate对象中@PostConstruct//注解作用: 在当前对象初始化完毕之后执行的方法public void initRabbittemplate(){rabbitTemplate.setConfirmCallback(this::confirm);}/*** 不论是否进入交换机,都会回调当前方法* @param correlationData 消息投递封装对象* @param ack 是否投递成功* @param exception 如果错误,错误原因*/@Overridepublic void confirm(CorrelationData correlationData, boolean ack, String exception) {if (ack) {System.out.println("消息进入了交换机成功{}");}else {System.out.println("消息进入了交换机失败{} 原因:"+exception);}}
}

生产者回退模式

application.properties

# 配置开启生产者的回退模式
spring.rabbitmq.publisher-returns=true

MessageConfirmRallback.java

package com.cubemall.controller;import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;/*
发送消息回调确认类:消息如果没有进入交换机,会回调当前类中的confirm*/
@Component
public class MessageConfirmRallback implements RabbitTemplate.ConfirmCallback,RabbitTemplate.ReturnCallback {//配置回调的方法@Autowiredprivate RabbitTemplate rabbitTemplate;//配置在当前对象注入之后,再设置当前对象到RabbitTemplate对象中@PostConstruct//注解作用: 在当前对象初始化完毕之后执行的方法public void initRabbittemplate(){rabbitTemplate.setConfirmCallback(this::confirm);rabbitTemplate.setReturnCallback(this::returnedMessage);}/*** 不论是否进入交换机,都会回调当前方法* @param correlationData 消息投递封装对象* @param ack 是否投递成功* @param exception 如果错误,错误原因*/@Overridepublic void confirm(CorrelationData correlationData, boolean ack, String exception) {if (ack) {System.out.println("消息进入了交换机成功{}");}else {System.out.println("消息进入了交换机失败{} 原因:"+exception);}}/*** 消息从交换机进入队列失败回调方法:只会在失败的情况下* @param message the returned message.* @param replyCode the reply code.* @param replyText the reply text.* @param exchange the exchange.* @param routingKey the routing key.*/@Overridepublic void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {System.out.println("消息从交换机进入队列失败: >>>>>>>");System.out.println("exchange = " + exchange);System.out.println("replyCode = " + replyCode);System.out.println("replyText = " + replyText);System.out.println("routingKey = " + routingKey);}
}

MessageController.java

package com.cubemall.controller;/*
目标: 搭建RabbitMQ高级特性演示环境
1.搭建消费者工程[复用之前工程]
2.搭建提供者工程[复用之前工程]
3.编写MessageController: 用来发送消息
交换机
路由键
消息内容
4.RabbitMQ配置交换机和队列,及路由键
5.编写消费者监听思考问题: 生产者能百分之百将消息发送给消息队列吗?
不确定的
1.生产者如果发消息给MQ,消息在传输的过程中可能丢失。找不到交换机
2.交换机路由到队列,也存在丢失消息的可能性问题解决方案:
1.生产者确认模式
2.生产者回退模式目标: 演示生产者确认的效果,消息百分百进入交换机
实现步骤:
1.配置开启生产者确认模式
2.编写生产者确认回调方法,处理业务逻辑
3.在RabbitMQ模板对象中,设置回调逻辑
4.测试请求一下目标2: 消息能够从交换机百分百进入到队列
实现步骤:
1.配置开启生产者回退模式
2.编写生产者回退的回调方法
3.设置回退回调方法
4.测试*/import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class MessageController {//发送消息接口@Autowiredprivate RabbitTemplate rabbitTemplate;//定义发送消息的接口@RequestMapping("/direct/sendMsg")public String sendMsgtoMQ(String exchange,String routingKey,String msg){rabbitTemplate.convertAndSend(exchange,routingKey,msg);return "已投递";}
}

消费者手动确认

application.properties

# 配置开启消费端手动签收
spring.rabbitmq.listener.simple.acknowledge-mode=manual
spring.rabbitmq.listener.direct.acknowledge-mode=manual# 配置开启重试
spring.rabbitmq.listener.direct.retry.enabled=true

ConsumerAckQueueListener.java

package com.cubemall.listeners;import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;import java.io.IOException;/*
消费者消息队列监听器
问题: 消费者能不能百分百接收到请求,而且业务逻辑处理出现异常,消息还能不能算接收到呢?目标: 演示消费者手动确认的过程
实现步骤:
1.编写监听器类 和对于监听的方法,编写手动签收的业务逻辑
2.配置开启手动签收
3.测试*/
@Component
@RabbitListener(queues = "order.A")
public class ConsumerAckQueueListener {//处理消息方法@RabbitHandlerpublic void simpleHandler(String msg, Message message, Channel channel) throws IOException {System.out.println("下单消息{},内容为: " + msg);//获取消息的投递标签long deliveryTag = message.getMessageProperties().getDeliveryTag();try {if (msg.contains("苹果")) {throw new RuntimeException("不允许售卖苹果手机");}//签收消息/*** 参数1: 投递标签* 参数2: 是否是批量签收,true一次性签收所有消息,如果是false则只签收当前消息*/channel.basicAck(deliveryTag,false);System.out.println("签收成功{}");} catch (IOException e) {//e.printStackTrace();//参数1: 投递标签//参数2: 是否批量//参数3: 是否重回队列channel.basicNack(deliveryTag,false,true);System.out.println("签收失败{}");}//拒绝签收消息: 出现异常了,拒绝签收}
}

死信队列

死信队列

延时队列

延时队列

消费者消息队列监听器
问题1: 消费者能不能百分百接收到请求,而且业务逻辑处理出现异常,消息还能不能算接收到呢?

目标: 演示消费者手动确认的过程
实现步骤:
1.编写监听器类 和对于监听的方法,编写手动签收的业务逻辑
2.配置开启手动签收
3.测试

问题2: 消息在队列中,如果没有被消费者消费?
TTL–> Time to Live (存活时间/有效期)
目标: 演示消息队列中消息失效超时过程
步骤:
1.配置新的队列order.B,设置队列内消息的超时时间5s x-message-ttl
2.将队列绑定order_exchange交换机上
3.发送消息,测试

问题3: 消息发送失败了,消息丢失了?消息有效期到了
死信队列: 当消息失效了,统一进入的一个队列,这个队列称之为死信队列
主要有三种情况:
1.到达了消息队列容量上限!
2.消费者如果拒绝签收,不重回队列!
3.消息超时了!

目标: 演示成为死信的过程
步骤:
1.建立死信队列deadQueue
2.建立死信交换机deadExchange
3.死信队列绑定死信交换机:order.dead
4.队列order.B绑定死信交换机 x-dead-letter-exchange x-dead-letter-routing-key
5.向队列发送消息,测试死信交换机

需求: 1.新用户注册成功7天后,发送消息问候?
2.下单后,30分钟未支付,取消订单,回滚票
延迟队列: 消息进入队列后不会被消费,只有到达指定的时间后才会被消费!

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

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

相关文章

docker desktop运行rabittmq容器,控制台无法访问

docker desktop运行rabittmq容器,控制台无法访问 启动过程:…此处缺略,网上一大堆 原因 原因是在Docker上运行的RabbitMQ,默认情况下是没有启用管理插件和管理页面的 解决办法 使用命令 docker exec -it 容器id /bin/bash 进…

Tailwind 安装使用

Tailwind 安装使用 前言 CSS原子化——本文将详细介绍如何在Vue Vite npm环境下安装、配置并使用Tailwind CSS! 文章目录 Tailwind 安装使用前言一、Tailwind 在 Vue Vite 项目中的安装1. 创建Vue项目2. 安装Tailwind CSS3. 初始化Tailwind配置4. 修改文件 tai…

centos7安装playwright踩坑记录

Python版本安装 Installation | Playwright Python 1. 安装pytest-playwright pip3 install pytest-playwright报错:提示找不到pytest-playwright 原因:服务器Python版本3.6.8太低,貌似pytest-playwright最低支持3.7 解决方法&#xff1…

函数(C语言)

1:函数的概念 函数的概念我们在初中的时候就已经听过了。 在C语言中也引入了函数,也可以叫子程序 C语言中的函数就是一个完成某项特定的任务的一小段代码 这段代码是有特殊的写法和调用方法的。其实C语言的程序也是由无数个小的函数组成的。 也就是&…

VMWare安装包及安装过程

虚拟机基本使用 检查自己是否开启虚拟化 如果虚拟化没有开启,需要自行开启:百度加上自己电脑的品牌型号,进入BIOS界面开启 什么是虚拟机 所谓的虚拟机,就是在当前计算机系统中,又开启了一个虚拟系统 这个虚拟系统&…

基于SVD奇异值分解的图像压缩算法(Python实现)

前言 SVD其实和PCA类似,就是丢入一个特征矩阵 X ,输出另外一个特征矩阵 X′ , X′ 的维度要比原来的X 要低。并且里面的变量都是原来的变量的线性组合,所以含义也变得不好解释。 简单来说就是数据压缩,特征降维的一种技术&#…

国产AI图片工具,全部免费亲测实用!

近AI生图功能火出圈了,各家大厂都拿出了看家本领,今天就来聊聊即梦AI、通义万相、奇域AI和腾讯元宝的AI生图功能,看看它们各有什么特色吧! 一、Dreamina 字节旗下的AI智能平台,简单实用的图片生成,对中国元…

C++ 二叉搜索树

二叉搜索树的概念 二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树: 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值 它的左右…

推荐一款3D建模软件:Agisoft Metashape Pro

Agisoft Metashape Pro是一款强大的多视点三维建模设计辅助软件,Agisoft Metashape是一款独立的软件产品,可对数字图像进行摄影测量处理,并生成3D空间数据,用于GIS应用,文化遗产文档和视觉效果制作,以及间接…

IntelliJ+SpringBoot项目实战(四)--快速上手数据库开发

对于新手学习SpringBoot开发,可能最急迫的事情就是尽快掌握数据库的开发。目前数据库开发主要流行使用Mybatis和Mybatis Plus,不过这2个框架对于新手而言需要一定的时间掌握,如果快速上手数据库开发,可以先按照本文介绍的方式使用JdbcTemplat…

Linux高阶——1110—线程安全问题解决方法

1、同步、异步、阻塞、非阻塞 同步过程:发起调用,调用者需要等待被调用者的结果 异步过程:发起调用,无需等待被调用的结果,当有结果后,此结果传出,无需主动获取 阻塞和非阻塞:发起…

STM32cubemx+Proteus仿真和keil5联合调试

前面两步 STM32cubemx生成代码 https://blog.csdn.net/weixin_52733843/article/details/143637304 Proteus新建工程 https://blog.csdn.net/weixin_52733843/article/details/143578853 1 *Proteus仿真联合调试* 在Proteus中,双击STM32F103C6芯片&#xff0c…

初识算法 · 位运算常见总结(1)

目录 前言: 位运算基本总结 部分题目代码 前言: ​本文的主题是位运算,通过常见的知识点讲解,并且会附上5道简单的题目,5道题目的链接分别为:191. 位1的个数 - 力扣(LeetCode) 1…

visualvm远程连接Docker容器中部署的java应用并监控

visualvm远程连接Docker容器中部署的java应用 前言 jdk1.8中自带了,java11中需要单独下载 下载地址 visualvm下载地址 简介 java虚拟机监控,故障排查及性能分析工具。 网络配置 局域网与docker内网打通,请参考:办公网络与Docker内…

NVIDIA RTX 系统上使用 llama.cpp 加速 LLM

NVIDIA RTX 系统上使用 llama.cpp 加速 LLM 文章目录 NVIDIA RTX 系统上使用 llama.cpp 加速 LLMllama.cpp 概述llama.cpp 在 NVIDIA RTX 上的加速性能使用 llama.cpp 构建的开发人员生态系统使用 llama.cpp 在 RTX 平台上加速的应用程序开始使用 适用于 Windows PC 的 NVIDIA …

信息收集系列(二):ASN分析及域名收集

内容预览 ≧∀≦ゞ 信息收集系列(二):ASN分析及域名收集前言一、ASN 分析1. 获取 ASN 码2. 使用 ASNMap 获取 IP 范围3. 将 IP 范围转化为 IP 列表 二、关联域名收集1. 顶级域(TLD)收集测试方法 2. 根域名收集常用方法…

揭秘:b站可以通过弹幕查询到发送者吗?答案是:不可行

查找发送者 发弹幕被找到 最近,我的一个好兄弟遇到了这样一个问题:他在b站发弹幕,结果被人找到了。他对此很困惑:“发送弹幕不是匿名的吗?只有评论才能看到用户名啊,难道发弹幕也可以被找到吗&#xff1f…

安装mysql、Navicat 17

1.安装mysql 下载地址 https://downloads.mysql.com/archives/installer/ 选择最新版本或者你需要的版本 点击第二个Download下载 下载完毕后双击启动,之后是这个页面 选Custom(第四个)自定义安装,可以将mysql安装到自定义目录…

人工智能助手是否让程序员技能退化?

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

RecyclerView进阶知识讲解

在 Android 开发中,RecyclerView 是一种高效的列表和网格布局控件,用于显示大规模数据。尽管基本使用方法简单,但深入理解并掌握其高级进阶用法能大幅提升用户体验和应用性能。下面,我将从布局管理、动画和手势、自定义缓存、优化…