RabbitMQ可靠傳輸——持久性、發送方確認

一、持久性

前面學習消息確認機制時,是為了保證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;基礎…

從乳制品行業轉型看智能化升級新機遇——兼談R2AIN 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;真正讓圖表產生價值的&…