亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

RabbitMQ中死信隊列和延遲隊列如何使用

發布時間:2022-05-30 10:34:52 來源:億速云 閱讀:195 作者:zzz 欄目:開發技術

這篇文章主要講解了“RabbitMQ中死信隊列和延遲隊列如何使用”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“RabbitMQ中死信隊列和延遲隊列如何使用”吧!

死信隊列

簡介

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

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

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

  • 消息過期;

  • 隊列達到最大長度。

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

為隊列添加DLX的方法

法1:代碼方式

//創建 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());

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

Web管理頁面結果

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

RabbitMQ中死信隊列和延遲隊列如何使用

圖1-1

案例分析

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

RabbitMQ中死信隊列和延遲隊列如何使用

圖1-2

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

延遲隊列

簡介

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

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

  • 方案1:采用rabbitmq-delayed-message-exchange 插件實現。(RabbitMQ 3.6.x開始支持)

  • 方案2:通過前面所介紹的DLX和TTL模擬出延遲隊列的功能。

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

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

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

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

RabbitMQ中死信隊列和延遲隊列如何使用

圖2-1

使用場景

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

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

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

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

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

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

感謝各位的閱讀,以上就是“RabbitMQ中死信隊列和延遲隊列如何使用”的內容了,經過本文的學習后,相信大家對RabbitMQ中死信隊列和延遲隊列如何使用這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

苍溪县| 田东县| 商水县| 山西省| 武义县| 五大连池市| 屏南县| 新竹市| 邵阳县| 石景山区| 清镇市| 龙泉市| 沙田区| 鸡西市| 扎囊县| 方山县| 江都市| 宁远县| 大竹县| 武定县| 华亭县| 施甸县| 黄平县| 广汉市| 聂拉木县| 姚安县| 耒阳市| 西华县| 桦甸市| 农安县| 城步| 兴安县| 闽清县| 临海市| 达日县| 内黄县| 林口县| 贵阳市| 义乌市| 双柏县| 高雄县|