RabbitMQ死信隊列


什么是TTL

 

RabbitMQ的TTL全稱為Time-To-Live,表示的是消息的有效期。消息如果在隊列中一直沒有被消費並且存在時間超過了TTL,消息就會變成了"死信" (Dead Message),后續無法再被消費了。設置TTL有兩種方式:

 

第一種是聲明隊列的時候,在隊列的屬性中設置,這樣該隊列中的消息都會有相同的有效期;
第二種是發送消息時給消息設置屬性,可以為每條消息都設置不同的TTL。

如果兩種方式都設置了,則以設置的較小的為准。兩者的區別:如果聲明隊列時設置了有效期,則消息過期了就會被刪掉;如果是發消息時設置的有效期,消息過期了也不會被立馬刪掉,因為這時消息是否過期是在要投遞給消費者時判斷的。至於為啥要這樣處理很容易想清楚:第一種方式隊列的消息有效期都一樣,先入隊的在隊列頭部,頭部也是最早要過期的消息,RabbitMQ起一個定時任務從隊列的頭部開始掃描是否有過期消息即可;第二種方式每條消息的過期時間不同,所以只有遍歷整個隊列才可以篩選出來過期的消息,這樣效率太低了,而且消息量大了之后根本不可行的,可以等到消息要投遞給消費者時再判斷刪除,雖然刪除的不夠及時但是不影響功能,其實就是用空間換時間。

 

如果不設置TTL,則表示此消息永久有效(默認消息是不會失效的)。如果將TTL設為0,則表示如果消息不能被立馬消費則會被立即丟掉,這個特性可以部分替代RabbitMQ3.0以前支持的immediate參數,之所以所部分代替,是應為immediate參數在投遞失敗會有basic.return方法將消息體返回(這個功能可以利用死信隊列來實現)。

設置TTL

1、設置隊列TTL

屬性名為x-message-ttl,單位為毫秒

2、代碼設置

 設置隊列TTL

設置消息TTL

3、查看隊列

3、設置隊列的過期時間

上面在web管控台添加隊列的時候,我們看到有一個x-expires參數,可以讓隊列在指定時間內 "未被使用" 的話會自動過期刪除,未使用的意思是 queue 上沒有任何 consumer,queue 沒有被重新聲明,並且在過期時間段內未調用過 basic.get 命令。該方式可用於,例如,RPC-style 的回復 queue, 其中許多queue 會被創建出來,但是卻從未被使用。

服務器會確保在過期時間到達后 queue 被刪除,但是不保證刪除的動作有多么的及時。在服務器重啟后,持久化的queue 的超時時間將重新計算。 x-expires 參數值以毫秒為單位,並且服從和 x-message-ttl 一樣的約束條件,且不能設置為 0 。所以,如果該參數設置為 1000 ,則表示該 queue 如果在 1s之內未被使用則會被刪除。

DLX-死信交換機

 

1、DLX是什么
DLX是Dead-Letter-Exchange的簡寫,意思是死信交換機。

 

它的作用其實是用來接收死信消息(dead message)的。那什么是死信消息呢?一般消息變成死信消息有如下幾種情況:

 

消息被拒絕(Basic.Reject/Basic.Nack) ,井且設置requeue 參數為false
消息過期
隊列達到最大長度
當消息在一個隊列中變成了死信消息后,可以被發送到另一個交換機,這個交換機就是DLX,綁定DLX的隊列成為死信隊列。當這個隊列中存在死信時, RabbitMQ 就會立即自動地將這個消息重新發布到設置的DLX 上去,進而被路由到綁定該DLX的死信隊列上。可以監聽這個隊列中的消息、以進行相應的處理,這個特性與將消息的TTL 設置為0 配合使用可以彌補imrnediate 參數的功能。

 

2、DLX有什么用
因為消息如果未被正常消費並設置了requeue為false時會進入死信隊列,我們可以監控消費死信隊列中消息,來觀察和分析系統的問題。DLX還有一個非常重要的作用,就是結合TTL實現延遲隊列(延遲隊列的使用范圍還是挺廣的:比如下單超過多長時間自動關閉;比如我們接入過第三方支付系統的同學一定知道,我們的訂單中會傳一個notify_url用於接收支付結果知,如果我們給第三方支付響應的不是成功的消息,其會隔一段時間繼續調用通知我們的notify_url,超過幾次后不再進行通知,一般通知頻率都是 0秒-5秒-30秒-5分鍾-30分鍾-1小時-6小時-12小時;比如我們的家用電器定時關機。。。。。。這些場景都是可以用延遲隊列實現的)。

 

3、DLX使用方式
下面在web管控台添加隊列的時候,我們看到有兩個DLX相關的參數:x-dead-letter-exchange和x-dead-letter-routing-key。x-dead-letter-exchange是設置隊列的DLX的;x-dead-letter-routing-key是設置死信消息進入DLX時的routing key的,這個是可以不設置的,如果不設置,則默認使用原隊列的routing key

 

 

私信流程

 

1消息發送到交換機normal_exchange,然后路由到隊列normal_queue上
2因為隊列normal_queue沒有消費者,消息過期后成為死信消息
3死信消息攜帶設置的x-dead-letter-routing-key=dlx.test進入到死信交換機dlx_exechage
4dlx_exechage與dlx_queue綁定的routing key為"dlx.*",死信消息的路由鍵dlx.test符合該規則被路由到dlx.queue上面。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM