最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解RabbitMQ中死信隊列和延遲隊列的使用詳解

 更新時間:2022年05月28日 09:11:15   作者:IT利刃出鞘  
這篇文章主要為大家介紹了RabbitMQ中死信隊列和延遲隊列的原理與使用,這也是Java后端面試中常見的問題,感興趣的小伙伴可以了解一下

簡介

本文介紹RabbitMQ的死信隊列和延遲隊列。

本內(nèi)容也是Java后端面試中常見的問題。

死信隊列

簡介

DLX,全稱為Dead-Letter-Exchange,可以稱之為死信交換器,也有人稱之為死信郵箱。當消息在一個隊列中變成死信(dead message)之后,它能被重新被發(fā)送到另一個交換器中,這個交換器就是DLX,綁定DLX的隊列就稱之為死信隊列。

以下幾種情況會導致消息變成死信:

  • 消息被拒絕(Basic.Reject/Basic.Nack),并且設(shè)置requeue參數(shù)為false;
  • 消息過期;
  • 隊列達到最大長度。

DLX是一個正常的交換器,和一般的交換器沒有區(qū)別,它能在任何的隊列上被指定,實際上就是設(shè)置某個隊列的屬性。當這個隊列中存在死信時,RabbitMQ就會自動地將這個消息重新發(fā)布到設(shè)置的DLX上去,進而被路由到另一個隊列,即死信隊列??梢员O(jiān)聽這個隊列中的消息以進行相應的處理,這個特性與將消息的TTL設(shè)置為0配合使用可以彌補immediate參數(shù)的功能。

為隊列添加DLX的方法

法1:代碼方式

//創(chuàng)建 DLX: dlx_exchange
channel.exchangeDeclare("dlx_exchange", "direct" );
Map<String, Object> args = new HashMap<String, Object>;
args.put("x-dead-letter-exchange", "dlx_exchange");
//為隊列myqueue添加DLX
channel.queueDeclare("myqueue", false, false, false, args);

也可以為這個DLX指定路由鍵。(如果沒有特殊指定,則使用原隊列的路由鍵)

args.put("x-dead-letter-routing-key","dlx-routing-key"); 

法2:命令方式

rabbitmqctl set_policy DLX ".*" '{"dead-letter-exchange":"dlx_exchange"}' --apply-to queues

示例

代碼

channel.exchangeDeclare("exchange.dlx", "direct", true);
channel.exchangeDeclare("exchange.normal", "fanout", true);
Map<String, Object> args = new HashMap<String, Object>();
args.put("x-message-ttl", 10000);
args.put("x-dead-letter-exchange" , "exchange.dlx");
args.put("x-dead-letter-routing-key" , "routingkey");
channel.queueDeclare("queue.normal" , true, false, false, args);
channel.queueBind("queue.normal", "exchange.normal", "");
channel.queueDeclare("queue.dlx", true, false, false, null);
channel.queueBind("queue.dlx", "exchange.dlx" , "routingkey");
channel.basicPublish("exchange.normal" , "rk",
MessageProperties.PERSISTENT_TEXT_PLAIN, "dlx".getBytes());

這里創(chuàng)建了兩個交換器exchange.normal和exchange.dlx,分別綁定兩個隊列queue.normal和queue.dlx。

Web管理頁面結(jié)果

由下圖(圖1-1)的Web管理頁面可以看出,兩個隊列都被標記了“D”,這個是durable的縮寫,即設(shè)置了隊列持久化。queue.normal這個隊列還配置了TTL、DLX和DLK,其中DLX指的是
x-dead-letter-routing-key這個屬性。 

圖1-1

案例分析

參考下圖(圖1-2),生產(chǎn)者首先發(fā)送一條攜帶路由鍵為“rk”的消息,然后經(jīng)過交換器exchange.normal順利地存儲到隊列queue.normal中。由于隊列queue.normal設(shè)置了過期時間為10s,在這10s內(nèi)沒有消費者消費這條消息,那么判定這條消息為過期。由于設(shè)置了DLX,過期之時,消息被丟給交換器exchange.dlx中,這時找到與exchange.dlx匹配的隊列queue.dlx,最后消息被存儲在queue.dk這個死信隊列中。 

圖1-2

對于RabbitMQ來說,DLX是一個非常有用的特性。它可以處理異常情況下,消息不能夠被消費者正確消費(消費者調(diào)用了Basic.Nack或者Basic.Reject)而被置入死信隊列中的情況,后續(xù)分析程序可以通過消費這個死信隊列中的內(nèi)容來分析當時所遇到的異常情況,進而可以改善和優(yōu)化系統(tǒng)。DLX配合TTL使用還可以實現(xiàn)延遲隊列的功能,詳細請看下一節(jié)。

延遲隊列

簡介

延遲隊列用來存放延遲消息。延遲消息:指當消息被發(fā)送以后,不想讓消費者立刻拿到消息,而是等待特定時間后,消費者才能拿到這個消息進行消費。

在AMQP協(xié)議中,或者RabbitMQ本身沒有直接支持延遲隊列的功能,但是有兩種方案來間接實現(xiàn):

  • 方案1:采用rabbitmq-delayed-message-exchange 插件實現(xiàn)。(RabbitMQ 3.6.x開始支持)
  • 方案2:通過前面所介紹的DLX和TTL模擬出延遲隊列的功能。

在圖1-2中,不僅展示的是死信隊列的用法,也是延遲隊列的用法,對于queue.dlx這個死信隊列來說,同樣可以看作延遲隊列。假設(shè)一個應用中需要將每條消息都設(shè)置為10秒的延遲,

生產(chǎn)者通過exchange.normal這個交換器將發(fā)送的消息存儲在queue.normal這個隊列中。消費者訂閱的并非是queue.normal這個隊列,而是queue.dlx這個隊列。當消息從queue.normal這個隊列中過期之后被存入queue.dlx這個隊列中,消費者就恰巧消費到了延遲10秒的這條消息。

在真實應用中,對于延遲隊列可以根據(jù)延遲時間的長短分為多個等級,一般分為5秒、10秒、30秒、1分鐘、5分鐘、10分鐘、30分鐘、1小時這幾個維度,當然也可以再細化一下。

以下圖(圖2-1)為例進行說明。為簡化,只設(shè)置5秒、10秒、30秒、1分鐘這四個等級。根據(jù)需求的不同,生產(chǎn)者發(fā)送消息的時候通過設(shè)置不同的路由鍵,將消息發(fā)送到與交換器綁定的不同的隊列中。這里隊列也分別配置了DLX和相應的死信隊列,當相應的消息過期時,就會轉(zhuǎn)存到相應的死信隊列(即延遲隊列)中,這樣消費者根據(jù)業(yè)務(wù)自身的情況,分別選擇不同延遲等級的延遲隊列進行消費。

圖2-1

使用場景

延遲隊列的使用場景有很多,比如:

用戶下訂單場景:用戶下單后有30分鐘的時間支付,若30分鐘內(nèi)沒有支付,則將這個訂單取消。

方案:用戶下單后將取消訂單的消息發(fā)送到延遲隊列,延遲時間設(shè)置為30分鐘。取消訂單這個消息的訂閱者程序在30分鐘后收到消息,判斷該訂單的狀態(tài)是否為已支付,若還沒支付,則將該訂單狀態(tài)設(shè)置為:已取消。

定時遙控場景:用戶想用手機遠程遙控家里的智能設(shè)備在指定的時間工作。

方案:假設(shè)用戶想要的操作是:開啟熱水器。首先,將開啟熱水器這個消息發(fā)送到延遲隊列,延遲時間設(shè)置到用戶想要的時間到現(xiàn)在時間的差值。開啟熱水器這個消息的訂閱者程序在指定時間收到消息,再將指令推送到智能設(shè)備。

需要注意的是,延遲隊列的消息是不能取消的,解決方案是:在消費消息的時候判斷這個消息對應的業(yè)務(wù)的當前狀態(tài)。例如:對于取消訂單來說,收到消息時,讀取這個消息所對應的數(shù)據(jù)庫信息,如果已經(jīng)是已付款狀態(tài)了,就不進行任何操作了,如果是未支付狀態(tài),則改為已取消。

到此這篇關(guān)于詳解RabbitMQ中死信隊列和延遲隊列的使用詳解的文章就介紹到這了,更多相關(guān)RabbitMQ死信隊列 延遲隊列內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java使用Kaptcha實現(xiàn)簡單的驗證碼生成器

    Java使用Kaptcha實現(xiàn)簡單的驗證碼生成器

    這篇文章主要為大家詳細介紹了Java如何使用Kaptcha實現(xiàn)簡單的驗證碼生成器,文中的示例代碼講解詳細,具有一定的借鑒價值,有需要的小伙伴可以參考下
    2024-02-02
  • java報錯:“錯誤:編碼GBK?的不可映射字符”解決辦法

    java報錯:“錯誤:編碼GBK?的不可映射字符”解決辦法

    當Java源代碼中包含中文字符時,我們在用javac編譯時會出現(xiàn)“錯誤:編碼GBK的不可映射字符”,這篇文章主要給大家介紹了關(guān)于java報錯:“錯誤:編碼GBK?的不可映射字符”的解決辦法,需要的朋友可以參考下
    2024-08-08
  • Java自定義映射resultMap定義及用法

    Java自定義映射resultMap定義及用法

    MyBatis的每一個查詢映射的返回類型都是ResultMap,當我們提供返回類型屬性是resultType時,MyBatis會自動給我們把對應值賦給resultType所指定對象的屬性,當我們提供返回類型是resultMap時,將數(shù)據(jù)庫中列數(shù)據(jù)復制到對象的相應屬性上,可以用于復制查詢,兩者不能同時用
    2022-11-11
  • Spring?boot?Jpa添加對象字段使用數(shù)據(jù)庫默認值操作

    Spring?boot?Jpa添加對象字段使用數(shù)據(jù)庫默認值操作

    這篇文章主要介紹了Spring?boot?Jpa添加對象字段使用數(shù)據(jù)庫默認值操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • java解壓zip文件示例

    java解壓zip文件示例

    這篇文章主要介紹了java解壓zip文件示例,在獲得一個以Zip格式壓縮的文件之后,需要將其進行解壓縮,還原成壓縮前的文件,下面是代碼示例
    2014-03-03
  • Spring boot整合mybatis實現(xiàn)過程圖解

    Spring boot整合mybatis實現(xiàn)過程圖解

    這篇文章主要介紹了Spring boot整合mybatis實現(xiàn)過程圖解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-08-08
  • Mybatis-plus數(shù)據(jù)權(quán)限D(zhuǎn)ataPermissionInterceptor實現(xiàn)

    Mybatis-plus數(shù)據(jù)權(quán)限D(zhuǎn)ataPermissionInterceptor實現(xiàn)

    本文主要介紹了Mybatis-plus數(shù)據(jù)權(quán)限D(zhuǎn)ataPermissionInterceptor實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-07-07
  • 使用HttpClient實現(xiàn)文件的上傳下載方法

    使用HttpClient實現(xiàn)文件的上傳下載方法

    下面小編就為大家?guī)硪黄褂肏ttpClient實現(xiàn)文件的上傳下載方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-12-12
  • 解決IntelliJ?IDEA輸出中文顯示為問號問題的有效方法

    解決IntelliJ?IDEA輸出中文顯示為問號問題的有效方法

    最近剛學到文件字節(jié)流這里,但輸出中文時,出現(xiàn)了控制臺輸出問號的情況,所以下面這篇文章主要給大家介紹了關(guān)于如何解決IntelliJ?IDEA輸出中文顯示為問號問題的有效方法,需要的朋友可以參考下
    2022-07-07
  • 基于mybatis-plus-generator實現(xiàn)代碼自動生成器

    基于mybatis-plus-generator實現(xiàn)代碼自動生成器

    這篇文章專門為小白準備了入門級mybatis-plus-generator代碼自動生成器,可以提高開發(fā)效率。文中的示例代碼講解詳細,感興趣的可以了解一下
    2022-05-05

最新評論

偃师市| 承德县| 阳朔县| 石狮市| 聂拉木县| 陆良县| 柳河县| 惠安县| 内黄县| 南城县| 老河口市| 郴州市| 新蔡县| 沁阳市| 淮滨县| 汝南县| 东城区| 历史| 家居| 木里| 雅安市| 聊城市| 平遥县| 吉林省| 定西市| 湄潭县| 招远市| 静安区| 兴文县| 宣恩县| 微博| 长寿区| 石狮市| 揭西县| 张家川| 卫辉市| 永胜县| 沈阳市| 德格县| 南郑县| 乌拉特前旗|