一、持久性

前面学习消息确认机制时,是为了保证Broker到消费者直接的可靠传输的,但是如果是Broker出现问题(如停止服务),如何保证消息可靠性?对此,RabbitMQ提供了持久化功能:

持久化分为三种:1. 交换机持久化   2. 队列持久化   3.消息持久化

1.1 交换机持久化

一、交换机持久化方法

声明交换机时,将durable置为true即可,如果不指定,默认为true

二、交换机持久化的作用

避免了当Broker重启时,未重新执行交换机声明代码,而导致生产者消息无法路由


1.2 队列持久化

一、队列持久化方法

在声明队列时,使用durable方法声明的队列为持久化队列,使用nonDurable声明的队列为非持久化队列

对应管理界面:

二、队列持久化的作用

在RabbitMQ服务器重启时,未持久化的队列将丢失,持久化队列保留


1.3 消息持久化

 一、消息持久化方法

前面在发送消息时,都是直接指定一个字符串来发送消息,如:


我们先进入convertAndSend方法,观察其源码:

接下来再进入MessageProperties,观察其源码:

可以看到,不指定消息是否持久化,默认为持久化

也就是说,如果要指定消息为非持久化,就选哟给convertAndSend传入一个Message对象而不是仅传一个消息字符串,接下来学习如何设置消息非持久化:

1> 创建一个Message对象

 Message message = new Message("persistent test...".getBytes(),new MessageProperties());

2> 获取MessageProperties对象,通过setDeliveryMode方法设置消息非持久化


/*
*如果要设置为持久化,可以直接换一个String的消息,也可以将这里的
*MessageDeliveryMode.NON_PERSISTENT改为MessageDeliveryMode.PERSISTENT
*/
message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.NON_PERSISTENT);

3> 将Message对象作为参数传递给converAndSend方法

rabbitTemplate.convertAndSend(Constants.NO_PERSISTENT_EXCHANGE,"",message);

整体代码:

二、消息持久化作用

RabbitMQ服务器重启时,未持久化的消息将丢失即使消息所在队列未持久化队列),持久化的消息将保留前提是消息所在的队列是持久化队列

但是,有了消息确认机制以及持久性就能保证消息传输的可靠性了吗?显然不是,因为消息确认机制保证的是Broker到消费者的可靠性 ,持久性保证的是Broker内部的可靠性,还有生产者到Broker的可靠性没有被保证,因此,RabbitMQ引入了publiser confirms(发送方确认)机制


二、发送方确认机制

前面已经学习了RabbitMQ核心机制之一——持久化,但是这就能保证消息传输的可靠性了吗?显然不是,如果发送方发送的消息没有到达Broker,又谈何持久化?因此,我们还需要了解RabbitMQ的发送方确认机制(通过事务也能解决,但是比较复杂,这里不谈)

publisher confirms 机制又包含两种模式

1> confirm确认模式

2> return退回模式

2.1 confirm确认模式

一、触发机制

Producer向Broker发送消息时,需要设置一个ConfirmCallback监听,这样消息无论是否到达exchange,这个监听都会触发,如果消息到达exchange,ACK为true,如果没有到达exchange,ACK为false


二、代码演示

1> 添加RabbitMQ配置

publisher-confirm-type: correlated #配置publisher confirm机制

2> 代码实现(队列、交换机随便声明一个就行,类型随意)

    @RequestMapping("/confirm")public String confirm(){//设置回调方法rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {@Overridepublic void confirm(CorrelationData correlationData, boolean ack, String cause) {System.out.println("执行confirm方法");if(ack){//ack为true,消息到达exchangeSystem.out.printf("接收到消息,消息ID:%s \n",correlationData==null ? null : correlationData.getId());}else {//ack为false,消息为到达exchangeSystem.out.printf("未接收到消息,消息ID:%s , cause: %s \n",correlationData==null ? null : correlationData.getId(),cause);}}});CorrelationData correlationData = new CorrelationData("1");//发送消息rabbitTemplate.convertAndSend(Constants.CONFIRM_EXCHANGE,"confirm","confirm test...",correlationData);return "消息发送成功";}

3>运行程序,测试接口

    1.正确发送消息(交换机名、routingKey存在)

消息发送成功,接下来查看控制台信息:

可以看到,交换机成功接收到消息

  2.错误发送消息(改为一个不存在的交换机名)

再次运行程序,访问接口,发送消息:

消息发送成功,查看控制台:

可以看到,消息并没有到达指定交换机,原因是不存在这个交换机。

  3.错误发送消息(改为一个不存在的routingKey)

运行程序,测试接口:

消息发送成功,查看控制台:

可以看到,在routingKey不存在的情况下,消息还是到达了交换机,但是这个消息一定是无法路由到队列的,因此就需要通过publsher confirm的 return退回模式 来解决

4> 上述代码编写存在的问题

  上面我们设置了ConfirmCallback监听经过测试,似乎并没有问题,但是仔细思考就会发现,我们在上面的代码中是通过rabbitTemplate这个对象来设置的,那岂不是前面所有使用rabbitTemplate的接口都被设置了监听?访问其它接口也一样会打印回调方法中的信息?

下面我们测试一下下面的方法:

运行程序,测试接口:

消息发送成功,查看控制台:

可以看到,同样会触发监听,为了避免这个问题,我们可以在config包中自己配置一个RabbitTemplate对象并注入进来:

@Configuration
public class RabbitTemplateConfig {@Beanpublic RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory){RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);return rabbitTemplate;}@Beanpublic RabbitTemplate confirmRabbitTemplate(ConnectionFactory connectionFactory){RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);//消息到达exchange时的回调方法rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {@Overridepublic void confirm(CorrelationData correlationData, boolean ack, String cause) {System.out.println("执行confirm方法");if(ack){//ack为true,表示消息到达交换机System.out.printf("接收到消息,消息ID:%s \n",correlationData==null ? null : correlationData.getId());}else{//ack为false,表示消息未到达交换机System.out.printf("未接收到消息,消息ID:%s , cause: %s \n",correlationData==null ? null : correlationData.getId(),cause);//业务逻辑,如重发等}}});//消息退回时的回调方法rabbitTemplate.setMandatory(true);rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {@Overridepublic void returnedMessage(ReturnedMessage returned) {System.out.println("消息退回: " + returned);}});return rabbitTemplate;}
}

2.2 return退回模式

 一、触发机制

当消息到达exchange后,需要路由到queue中,如果一条消息无法被任何queue消费(routingKey不存在或队列不存在),可以把消息退回给producer,退回时可以设置一个回调方法ReturnCallback,对消息进行处理


二、代码演示

   //消息退回时的回调方法rabbitTemplate.setMandatory(true);rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {@Overridepublic void returnedMessage(ReturnedMessage returned) {System.out.println("消息退回: " + returned);}});

修啊routingKey为一个不存在的routingKey:

运行程序,测试接口:

查看控制台:

可以看到,消息被退回


2.3 总结

publisher confirms 机制可以保证消息从生产者到Broker的可靠性,其中confirm模式工作在生产者到exchange之间,return模式工作在exchange到queue之间 

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

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

相关文章

(Java基础笔记vlog)Java中常见的几种设计模式详解

前言: 在 Java 编程里,设计模式是被反复使用、多数人知晓、经过分类编目的代码设计经验总结。他能帮助开发者更高效地解决常见问题,提升代码的可维护性、可扩展性和复用性。下面介绍Java 中几种常见的设计模式。 单例模式(Singlet…

(8)Spring Boot 原生镜像支持

Spring Boot 原生镜像支持 👉 点击展开题目 在Spring Boot 3.x中,如何设计一个支持GraalVM原生镜像的微服务?需要特别注意哪些限制? 📌 Spring Boot 3.x 原生镜像概述 Spring Boot 3.x 通过 Spring Native 项目提供了对 GraalVM 原生镜像的一流支持,使开发者能够将 S…

不使用SOAP,从PDF表单连接数据库

不使用SOAP协议,通过XFDF格式实现PDF表单与数据库交互的方法。该方法兼容免费的Adobe Reader,且无需特殊权限设置。 背景与问题 历史方案: Adobe曾提供ADBC接口(基于ODBC),但在Acrobat 9后被移除。SOAP方案在免费版Rea…

HTTP由浅入深

文章目录 概述特点URL HTTP 与 HTTPS概述HTTP 工作原理HTTPS 的作用区别总结 请求报文请求行常见请求方法请求头请求体Content-Type 详解常见场景 Content-Type 对应关系 响应报文响应行状态码详解1xx:信息响应(Informational)2xx&#xff1a…

Redis淘汰策略

Redis有八种淘汰策略 noeviction :不进行淘汰,直接报错。allkeys-lru :随机淘汰最久未使用的键。volatile-lru :从设置了过期时间的键中,随机淘汰最久未使用的键。allkeys-random :随机淘汰某个键。volati…

Maven打包SpringBoot项目,因包含SpringBootTest单元测试和Java预览版特性导致打包失败

SpringBoot启用Java预览版特性&#xff08;无测试类&#xff09; 在pom.xml文件中加入以下配置表示启用Java预览版 <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration>…

Makefile快速入门

简介‌&#xff1a; ‌ Makefile‌ 是一种用于自动化构建和管理软件项目的工具文件&#xff0c;通常与 make 命令配合使用。它通过定义‌规则‌&#xff08;rules&#xff09;来指定如何从源文件生成目标文件&#xff08;如可执行程序或库&#xff09;&#xff0c;并自动…

RISC-V 开发板 MUSE Pi Pro OpenCV结合Gstreamer实时显示CSI摄像头

视频讲解&#xff1a;RISC-V 开发板 MUSE Pi Pro OpenCV结合Gstreamer实时显示CSI摄像头_哔哩哔哩_bilibili RISC-V 开发板 MUSE Pi Pro OpenCV结合Gstreamer实时显示CSI摄像头 安装opencv相关库 sudo apt install libopencv-dev python3 python3-opencv 测试使用的CSI摄像头…

如何用JAVA手写一个Tomcat

一、初步理解Tomcat Tomcat是什么&#xff1f; Tomcat 是一个开源的 轻量级 Java Web 应用服务器&#xff0c;核心功能是 运行 Servlet/JSP。 Tomcat的核心功能&#xff1f; Servlet 容器&#xff1a;负责加载、实例化、调用和销毁 Servlet。 HTTP 服务器&#xff1a;监听端口…

短剧系统开发与抖音生态融合:短视频时代的新风口与商业机遇

在短视频内容井喷的时代&#xff0c;“短剧”作为一种新兴内容形态&#xff0c;正以惊人的速度抢占用户注意力。抖音、快手等平台日均播放量破亿的短剧作品&#xff0c;不仅催生了新的内容创作风口&#xff0c;更推动了短剧系统开发的巨大市场需求。本文将深度解析短剧系统开发…

《云原生安全攻防》-- K8s日志审计:从攻击溯源到安全实时告警

当K8s集群遭受入侵时&#xff0c;安全管理员可以通过审计日志进行攻击溯源&#xff0c;通过分析攻击痕迹&#xff0c;我们可以找到攻击者的入侵行为&#xff0c;还原攻击者的攻击路径&#xff0c;以便修复安全问题。 在本节课程中&#xff0c;我们将介绍如何配置K8s审计日志&am…

3dczml时间动态图型场景

在cesium中我们了可以使用czml数据来生成可以随时间变化而变化的物体. 首先导入czml数据 设置时间范围 id: "point" //物体在什么时间范围可用 availability:"2012-08-04T16:00:00Z/2012-08-04T16:05:00Z"position:{ //设置物体的起始时间 epoch:"…

超小多模态视觉语言模型MiniMind-V 训练

简述 MiniMind-V 是一个超适合初学者的项目&#xff0c;让你用普通电脑就能训一个能看图说话的 AI。训练过程就像教小孩&#xff1a;先准备好图文材料&#xff08;数据集&#xff09;&#xff0c;教它基础知识&#xff08;预训练&#xff09;&#xff0c;再教具体技能&#xf…

01-jenkins学习之旅-window-下载-安装-安装后设置向导

1 jenkins简介 百度百科介绍&#xff1a;Jenkins是一个开源软件项目&#xff0c;是基于Java开发的一种持续集成工具&#xff0c;用于监控持续重复的工作&#xff0c;旨在提供一个开放易用的软件平台&#xff0c;使软件项目可以进行持续集成。 [1] Jenkins官网地址 翻译&…

VPLC (VPLCnext) K8S

前序 在接触Virtual PLCnext Control的时候&#xff0c;我想过好几次如何将它运行在k8s上&#xff0c;由于对k8s的熟悉程度不够&#xff0c;跌跌撞撞尝试了很久&#xff0c;终于把vPLC部署在单机版的k8s上了。&#xff08;此教程仅为demo阶段&#xff0c;此教程仅为demo阶段&a…

OPC Client第5讲(wxwidgets):初始界面的事件处理;按照配置文件初始化界面的内容

接上一讲&#xff0c;即实现下述界面的事件处理代码&#xff1b;并且按照配置文件初始化界面的内容&#xff08;三、&#xff09; 事件处理的基础知识&#xff0c;见下述链接五、 OPC Client第3讲&#xff08;wxwidgets&#xff09;&#xff1a;wxFormBuilder&#xff1b;基础…

从乳制品行业转型看智能化升级新机遇——兼谈R²AIN SUITE的赋能实践

一、市场现状&#xff1a;乳制品行业迎来智能化转型关键期 中国乳制品行业在经历高速增长与深度调整后&#xff0c;已进入以"安全、效率、创新"为核心的新发展阶段。根据施耐德电气白皮书数据显示&#xff0c;2019年乳制品合格率达99.8%[1]&#xff0c;液态奶占据77…

[20250522]目前市场上主流AI开发板及算法盒子的芯片配置、架构及支持的AI推理框架的详细梳理

目前市场上主流AI开发板及算法盒子的芯片配置、架构及支持的AI推理框架的详细梳理

【Golang笔记03】error、panic、fatal错误处理学习笔记

Golang笔记&#xff1a;错误处理学习笔记 一、进阶学习 1.1、错误&#xff08;异常处理&#xff09; Go语言中也有和Java中的异常处理相关的机制&#xff0c;不过&#xff0c;在Go里面不叫异常&#xff0c;而是叫做&#xff1a;错误。错误分为三类&#xff0c;分别是&#x…

Python可视化设计原则

在数据驱动的时代&#xff0c;可视化不仅是结果的呈现方式&#xff0c;更是数据故事的核心载体。Python凭借其丰富的生态库&#xff08;Matplotlib/Seaborn/Plotly等&#xff09;&#xff0c;已成为数据可视化领域的主力工具。但工具只是起点&#xff0c;真正让图表产生价值的&…