RabbitMQ高級特性--TTL和死信隊列

目錄

1.TTL

1.1設置消息的TTL

1.1.1配置交換機&隊列

1.1.2發送消息

?1.1.3運行程序觀察結果

1.2設置隊列的TTL?

1.2.1配置隊列和交換機的綁定關系

1.2.2發送消息

1.2.3運行程序觀察結果

1.3兩者區別

2.死信隊列

2.1 聲名隊列和交換機

2.2正常隊列綁定死信交換機

2.3制造死信產生的條件

2.4 發送消息

2.5測試死信?

?2.6常見面試題

2.6.1死信隊列的概念

2.6.2死信的來源

2.6.3死信隊列的應?場景


1.TTL

TTL(Time to Live, 過期時間), 即過期時間. RabbitMQ可以對消息和隊列設置TTL.
當消息到達存活時間之后, 還沒有被消費,就會被自動清除。

1.1設置消息的TTL

目前有兩種方法可以設置消息的TTL

一是設置隊列的TTL,隊列中所有消息都有相同的過期時間,二是對消息本身進行單獨設置,每條消息的TTL可以不同,如果兩種方法一起使用,則消息的TTL以兩者之間較小的那個數值決定。

先看針對每條消息設置TTL

針對每條消息設置TTL的方法是在發送消息的方法中加入expiration的屬性參數,單位為ms

1.1.1配置交換機&隊列

//TTL
public static final String TTL_QUEUE = "ttl_queue";
public static final String TTL_EXCHANGE_NAME = "ttl_exchange";//ttl
//1. 交換機
@Bean("ttlExchange")
public Exchange ttlExchange() {return
ExchangeBuilder.fanoutExchange(Constant.TTL_EXCHANGE_NAME).durable(true).build(
);
}
//2. 隊列
@Bean("ttlQueue")
public Queue ttlQueue() {return QueueBuilder.durable(Constant.TTL_QUEUE).build();
}
//3. 隊列和交換機綁定 Binding
@Bean("ttlBinding")
public Binding ttlBinding(@Qualifier("ttlExchange") FanoutExchange exchange, 
@Qualifier("ttlQueue") Queue queue) {return BindingBuilder.bind(queue).to(exchange);
}

1.1.2發送消息

@RequestMapping("/ttl")
public String ttl(){String ttlTime = "10000";//10srabbitTemplate.convertAndSend(Constant.TTL_EXCHANGE_NAME, "", "ttl 
test...", messagePostProcessor -> {messagePostProcessor.getMessageProperties().setExpiration(ttlTime);return messagePostProcessor;});return "發送成功!";
}

?1.1.3運行程序觀察結果

發送消息后可以看到Ready數為1

十秒后,刷新頁面發現消息已消失

1.2設置隊列的TTL?

設置隊列的TTL的方法是在創建隊列時,加入x-message-ttl參數實現的,單位是ms

1.2.1配置隊列和交換機的綁定關系

public static final String TTL_QUEUE2 = "ttl_queue2";
//設置ttl
@Bean("ttlQueue2")
public Queue ttlQueue2() {//設置20秒過期return QueueBuilder.durable(Constant.TTL_QUEUE2).ttl(20*1000).build();
}
//3. 隊列和交換機綁定 Binding
@Bean("ttlBinding2")
public Binding ttlBinding2(@Qualifier("ttlExchange") FanoutExchange exchange, 
@Qualifier("ttlQueue2") Queue queue) {return BindingBuilder.bind(queue).to(exchange);
}

設置過期時間,也可以采用以下方式:

@Bean("ttlQueue2")
public Queue ttlQueue2() {Map<String, Object> arguments = new HashMap<>();arguments.put("x-message-ttl",20000);//20秒過期return
QueueBuilder.durable(Constant.TTL_QUEUE2).withArguments(arguments).build();
}

1.2.2發送消息

@RequestMapping("/ttl")public String ttl() {
// String ttlTime = "30000";//10s
// //發送帶ttl的消息
// rabbitTemplate.convertAndSend(Constant.TTL_EXCHANGE_NAME, "", "ttl test...", //messagePostProcessor -> {
// messagePostProcessor.getMessageProperties().setExpiration(ttlTime);
// return messagePostProcessor;
// });//發送不帶ttl的消息rabbitTemplate.convertAndSend(Constant.TTL_EXCHANGE_NAME, "", "ttl 
test...");return "發送成功!";}

1.2.3運行程序觀察結果

?運行后發現,新增了一個隊列,隊列Features有一個TTL標識

?發送消息后,可以看到Ready消息為1

采?發布訂閱模式, 所有與該交換機綁定的隊列都會收到消息

20s后,刷新頁面,發現消息已經刪除

?

?由于ttl_queue隊列, 未設置過期時間, 所以ttl_queue的消息未刪除。

1.3兩者區別

設置隊列TTL屬性的方法, ?旦消息過期, 就會從隊列中刪除
設置消息TTL的方法, 即使消息過期, 也不會馬上從隊列中刪除, 而是在即將投遞到消費者之前進?判定的
為什么這兩種方法的處理方法不一致?
因為設置隊列過期時間, 隊列中已過期的消息肯定在隊列頭部, RabbitMQ只要定期從隊頭開始掃描是否有過期的消息即可.
而設置消息TTL的方式, 每條消息的過期時間不同, 如果要刪除所有過期消息需要掃描整個隊列, 所以不如等到此消息即將被消費時再判定是否過期, 如果過期再進行刪除即可.

2.死信隊列

死信(dead message)簡單理解就是因為種種原因無法被消費的信息,就是死信

有死信,自然就有死信隊列。當消息在一個隊列中變成死信之后,它能被重新發送到另一個交換機中,這個交換機就是DLX(Dead Letter Exchange),綁定DLX的隊列,就稱為死信隊列(Dead Letter Queue)簡稱DLQ

消息變成死信主要有以下幾個原因:

1.消息被拒絕(Basic.Reject/Basic.Nack),并且設置requeue參數為false?

2.消息過期

3.隊列達到最大長度

2.1 聲名隊列和交換機

//死信隊列
public static final String DLX_EXCHANGE_NAME = "dlx_exchange";
public static final String DLX_QUEUE = "dlx_queue";
public static final String NORMAL_EXCHANGE_NAME = "normal_exchange";
public static final String NORMAL_QUEUE = “narmal_queue”;
/*** 死信隊列相關配置*/
@Configuration
public class DLXConfig {//死信交換機@Bean("dlxExchange")public Exchange dlxExchange(){return
ExchangeBuilder.topicExchange(Constant.DLX_EXCHANGE_NAME).durable(true).build()
;}//2. 死信隊列@Bean("dlxQueue")public Queue dlxQueue() {return QueueBuilder.durable(Constant.DLX_QUEUE).build();}//3. 死信隊列和交換機綁定 Binding@Bean("dlxBinding")public Binding dlxBinding(@Qualifier("dlxExchange") Exchange exchange, 
@Qualifier("dlxQueue") Queue queue) {return BindingBuilder.bind(queue).to(exchange).with("dlx").noargs();}//正常交換機@Bean("normalExchange")public Exchange normalExchange(){return
ExchangeBuilder.topicExchange(Constant.NORMAL_EXCHANGE_NAME).durable(true).buil
d();}//正常隊列@Bean("normalQueue")public Queue normalQueue() {return QueueBuilder.durable(Constant.NORMAL_QUEUE).build();}//正常隊列和交換機綁定 Binding@Bean("normalBinding")public Binding normalBinding(@Qualifier("normalExchange") Exchange 
exchange, @Qualifier("normalQueue") Queue queue) {return BindingBuilder.bind(queue).to(exchange).with("normal").noargs();}
}

2.2正常隊列綁定死信交換機

當這個隊列中存在死信時,RabbitMQ會自動的把這個消息重新發布到設置的DLX上,進而被路由到另一個隊列,即死信隊列,可以監聽這個死信隊列中的消息以進行相應的處理

@Bean("normalQueue")
public Queue normalQueue() {Map<String, Object> arguments = new HashMap<>();arguments.put("x-dead-letter-exchange",Constant.DLX_EXCHANGE_NAME);//綁定死信隊列arguments.put("x-dead-letter-routing-key","dlx");//設置發送給死信隊列的
RoutingKeyreturn QueueBuilder.durable(Constant.NORMAL_QUEUE).withArguments(arguments).build();
}

簡寫為

return QueueBuilder.durable(Constant.NORMAL_QUEUE).deadLetterExchange(Constant.DLX_EXCHANGE_NAME).deadLetterRoutingKey("dlx").build();

2.3制造死信產生的條件

@Bean("normalQueue")
public Queue normalQueue() {Map<String, Object> arguments = new HashMap<>();arguments.put("x-dead-letter-exchange",Constant.DLX_EXCHANGE_NAME);//綁定死
信隊列arguments.put("x-dead-letter-routing-key","dlx");//設置發送給死信隊列的
RoutingKey//制造死信產?的條件arguments.put("x-message-ttl",10000);//10秒過期arguments.put("x-max-length",10);//隊列?度return
QueueBuilder.durable(Constant.NORMAL_QUEUE).withArguments(arguments).build();
}

簡寫為:

return QueueBuilder.durable(Constant.NORMAL_QUEUE).deadLetterExchange(Constant.DLX_EXCHANGE_NAME).deadLetterRoutingKey("dlx").ttl(10*1000).maxLength(10L).build();

2.4 發送消息

@RequestMapping("/dlx")public void dlx() {//測試過期時間, 當時間達到TTL, 消息?動進?到死信隊列rabbitTemplate.convertAndSend(Constant.NORMAL_EXCHANGE_NAME, "normal", 
"dlx test...");//測試隊列?度
// for (int i = 0; i < 20; i++) {
// rabbitTemplate.convertAndSend(Constant.NORMAL_EXCHANGE_NAME, "normal", "dlx test...");
// }
// //測試消息拒收
// rabbitTemplate.convertAndSend(Constant.NORMAL_EXCHANGE_NAME, "normal", "dlx test...");}

2.5測試死信?

?程序啟動后觀察隊列:

隊列Features說明:
D: durable的縮寫, 設置持久化
TTL: Time to Live, 隊列設置了TTL
Lim: 隊列設置了?度(x-max-length)
DLX: 隊列設置了死信交換機(x-dead-letter-exchange)
DLK: 隊列設置了死信RoutingKey(x-dead-letter-routing-key)
測試過期時間,到達過期時間后,進入死信隊列:
發送之后:

?10s后:

?產者?先發送?條消息,然后經過交換器(normal_exchange)順利地存儲到隊列(normal_queue)中.由于隊列normal_queue設置了過期時間為10s, 在這10s內沒有消費者消費這條消息, 那么判定這條消息過期. 由于設置了DLX, 過期之時, 消息會被丟給交換器(dlx_exchange)中, 這時根據RoutingKey匹配, 找到匹配的隊列(dlx_queue), 最后消息被存儲在queue.dlx這個死信隊列里。

?2.6常見面試題

死信隊列作為RabbitMQ的高級特性,也是面試的一大重點

2.6.1死信隊列的概念

死信(Dead Letter)是消息隊列中的?種特殊消息, 它指的是那些?法被正常消費或處理的消息. 在消息隊列系統中, 如RabbitMQ, 死信隊列用于存儲這些死信消息

2.6.2死信的來源

1) 消息過期: 消息在隊列中存活的時間超過了設定的TTL
2) 消息被拒絕: 消費者在處理消息時, 可能因為消息內容錯誤, 處理邏輯異常等原因拒絕處理該消息. 如果拒絕時指定不重新?隊(requeue=false), 消息也會成為死信.
3) 隊列滿了: 當隊列達到最大長度, 無法再容納新的消息時, 新來的消息會被處理為死信.

2.6.3死信隊列的應?場景

對于RabbitMQ來說, 死信隊列是?個?常有?的特性. 它可以處理異常情況下,消息不能夠被消費者正確消費而被置?死信隊列中的情況, 應?程序可以通過消費這個死信隊列中的內容來分析當時所遇到的
異常情況, 進而可以改善和優化系統.
?如: 用戶支付訂單之后, ?付系統會給訂單系統返回當前訂單的?付狀態
為了保證?付信息不丟失, 需要使?到死信隊列機制. 當消息消費異常時, 將消息投?到死信隊列中, 由訂單系統的其他消費者來監聽這個隊列, 并對數據進行處理(比如發送?單等,進行人工確認).
場景的應?場景還有:
消息重試:將死信消息重新發送到原隊列或另?個隊列進行重試處理.
消息丟棄:直接丟棄這些?法處理的消息,以避免它們占?系統資源.
?志收集:將死信消息作為?志收集起來,?于后續分析和問題定位

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/74037.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/74037.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/74037.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【JavaEE】UDP數據報套接字編程

目錄 網絡編程基礎 基本概念 發送端和接收端 請求和響應 客戶端和服務端 常見的客戶端服務端模型 Socket套接字 TCP/UDP特點 Java數據報套接字通信模型(UDP通信) UDP數據報套接字編程 DatagramSocket 1.類定義 2.構造方法 3.核心方法 4.特性說明 DatagramPacke…

Spring Boot 3.4.3 基于 SpringDoc 2 和 Swagger 3 實現項目接口文檔管理

在現代企業級應用開發中&#xff0c;前后端分離已成為主流模式&#xff0c;前端負責界面呈現&#xff0c;后端專注提供 RESTful API 接口。然而&#xff0c;接口文檔的編寫和維護往往是開發過程中的痛點。Spring Boot 3.4.3 結合 SpringDoc 2 和 Swagger 3&#xff0c;為開發者…

構建大語言模型應用:數據準備(第二部分)

本專欄通過檢索增強生成&#xff08;RAG&#xff09;應用的視角來學習大語言模型&#xff08;LLM&#xff09;。 本系列文章 簡介數據準備&#xff08;本文&#xff09;句子轉換器向量數據庫搜索與檢索大語言模型開源檢索增強生成評估大語言模型服務高級檢索增強生成 RAG 如上…

Linux 隨機數據生成

目錄 一. /dev/urandom1.1 dd 命令1.2 head命令1.3 隨機字母 二. openssl 命令三. yes命令 一. /dev/urandom ?/dev/urandom 是 Linux 和 Unix 系統中的一個特殊文件&#xff0c;它是一個偽隨機數生成器&#xff0c;用于提供高吞吐量的隨機數據。 1.1 dd 命令 bs1M count10…

項目如何安裝本地tgz包并配置局部registry

一、判斷包來源是否正確 1. 檢查url curl <registry_url>2. 查看包是否存在 npm view <package_name> --registry<registry_url>二、局部registry配置步驟&#xff1a; 1. 全局配置 如果你希望對所有項目生效&#xff0c;可以將這行配置添加到全局.npmr…

QCustomPlot入門

QCustomPlot 是一個基于 Qt 的 C++ 繪圖庫,專注于高效、美觀的 2D 數據可視化。進入QCustomPlot下載頁,下載最新的完整包(包含:源碼、文檔、示例)。 一、核心架構設計 1. 分層架構模型 層級主要組件職責說明用戶接口層QCustomPlot 類提供頂層API,管理所有子組件邏輯控制…

C語言快速入門-C語言基礎知識

這個c語言入門&#xff0c;目標人群是有代碼基礎的&#xff0c;例如你之前學過javaSE&#xff0c;看此文章可能是更有幫助&#xff0c;會讓你快速掌握他們之間的差異&#xff0c;文章內容大部分都是泛談&#xff0c;詳細的部分我會在之后時間發布&#xff0c;我也在慢慢學習&am…

【商城實戰(91)】安全審計與日志管理:為電商平臺筑牢安全防線

【商城實戰】專欄重磅來襲!這是一份專為開發者與電商從業者打造的超詳細指南。從項目基礎搭建,運用 uniapp、Element Plus、SpringBoot 搭建商城框架,到用戶、商品、訂單等核心模塊開發,再到性能優化、安全加固、多端適配,乃至運營推廣策略,102 章內容層層遞進。無論是想…

信息安全工程師第 1 章

《信息安全工程師教程(第2版)》第一章 一、網絡信息安全基本概念與重要性 網絡信息安全定義 狹義:保障信息系統的機密性(C)、完整性(I)、可用性(A)——CIA三性。廣義:涵蓋國家安全、經濟安全、社會安全等的“大安全”。法律依據:《網絡安全法》定義網絡安全為防范攻…

為什么視頻文件需要壓縮?怎樣壓縮視頻體積即小又清晰?

在日常生活中&#xff0c;無論是為了節省存儲空間、便于分享還是提升上傳速度&#xff0c;我們常常會遇到需要壓縮視頻的情況。本文將介紹為什么視頻需要壓縮&#xff0c;壓縮視頻的好處與壞處&#xff0c;并教你如何使用簡鹿視頻格式轉換器輕松完成MP4視頻文件的壓縮。 為什么…

網絡空間安全(45)PHP入門學習

一、PHP文件與結構 PHP文件擴展名&#xff1a;PHP文件通常以.php作為擴展名&#xff0c;例如index.php。 PHP代碼嵌入&#xff1a;PHP代碼可以嵌入到HTML文件中&#xff0c;通常使用<?php ... ?>標簽包圍PHP代碼。短標簽<? ... ?>在某些配置下也可以使用&…

深入 OpenPDF:高級 PDF 生成與操作技巧

1 引言 1.1 項目背景 在許多企業級應用中,生成和操作 PDF 文檔是一個常見的需求。PDF(Portable Document Format)因其格式統一、易于打印和分發而被廣泛使用。本文將介紹如何使用 OpenPDF 庫在 Java 項目中生成和操作 PDF 文檔。 1.2 技術選型理由 OpenPDF:OpenPDF 是一…

力扣hot100——最長連續序列(哈希unordered_set)

題目鏈接&#xff1a;最長連續序列 1、錯解&#xff1a;數組做哈希表&#xff08;內存超出限制&#xff09; int longestConsecutive(vector<int>& nums) {vector<bool> hash(20000000010, false);for(int i0; i<nums.size();i){hash[1000000000nums[i]]t…

Qt中信號帶參傳值

在我們的Qt信號中是可以進行參數的傳遞的&#xff0c;不過格式上與寫普通函數不同。 這是頭文件中定義一個含參信號和一個含參槽函數 我們再來看它們兩個的綁定 。第一行的clicked()和on_btn_clicked()就是普通無參信號和槽的綁定&#xff1b;第二行就是上圖中兩個帶參信號和槽…

CSS3學習教程,從入門到精通, CSS3 列表控制詳解語法知識點及案例代碼(24)

CSS3 列表控制詳解 CSS 列表控制的語法知識點及案例代碼的詳細說明&#xff0c;包括 list-style-type、list-style-image、list-style-position 和 list-style 的用法。 1. list-style-type 屬性 list-style-type 屬性用于設置列表項標記的類型。 語法 list-style-type: v…

用Deepseek寫掃雷uniapp小游戲

掃雷作為Windows系統自帶的經典小游戲&#xff0c;承載了許多人的童年回憶。本文將詳細介紹如何使用Uniapp框架從零開始實現一個完整的掃雷游戲&#xff0c;包含核心算法、交互設計和狀態管理。無論你是Uniapp初學者還是有一定經驗的開發者&#xff0c;都能從本文中獲得啟發。 …

Dust3r、Mast3r、Fast3r

目錄 一.Dust3r 1.簡述 2.PointMap與ConfidenceMap 3.模型結構 4.損失函數 5.全局對齊 二.Mast3r 1.簡述 2.MASt3R matching 3.MASt3R sfm 匹配與標準點圖 BA優化 三.Fast3r 1.簡述 2.模型結構 3.損失函數 三維重建是計算機視覺中的一個高層任務&#xff0c;包…

學習不同電腦cpu分類及選購指南

學習不同電腦cpu分類及選購指南 關于電腦cpu 學習不同電腦cpu分類及選購指南一、CPU型號的核心組成與命名規則Intel命名規則:AMD命名規則:代數:具體型號:cpu后綴:Intel常見后綴及其含義:AMD后綴常見后綴及其含義:二、主流品牌CPU的分類與性能差異三、區分CPU型號的實用方…

【身份安全】零信任安全框架梳理(一)

目錄 零信任網絡安全防護理念一、定義零信任原則 二、零信任實現方式三、零信任的核心機制和思想1. 持續驗證&#xff08;Continuous Verification&#xff09;2. 多因素認證&#xff08;MFA&#xff09;與強身份驗證3. 細粒度權限控制&#xff08;最小權限原則&#xff09;4. …

【LeetCode Solutions】LeetCode 101 ~ 105 題解

CONTENTS LeetCode 101. 對稱二叉樹&#xff08;簡單&#xff09;LeetCode 102. 二叉樹的層序遍歷&#xff08;中等&#xff09;LeetCode 103. 二叉樹的鋸齒形層序遍歷&#xff08;中等&#xff09;LeetCode 104. 二叉樹的最大深度&#xff08;簡單&#xff09;LeetCode 105. 從…