1. 程式人生 > 其它 >rabbitmq 之mandatory和immediate 以及 備份交換器

rabbitmq 之mandatory和immediate 以及 備份交換器

1. 概述
  mandatory和immediate是AMQP協議中basic.publish方法中的兩個標識位,它們都有當訊息傳遞過程中不可達目的地時將訊息返回給生產者的功能。對於剛開始接觸RabbitMQ的朋友特別容易被這兩個引數搞混,這裡博主整理了寫資料,簡單講解下這兩個標識位。

  mandatory
    當mandatory標誌位設定為true時,如果exchange根據自身型別和訊息routeKey無法找到一個符合條件的queue,那麼會呼叫basic.return方法將訊息返回給生產者(Basic.Return + Content-Header + Content-Body);當mandatory設定為false時,出現上述情形broker會直接將訊息扔掉。

  immediate
    當immediate標誌位設定為true時,如果exchange在將訊息路由到queue(s)時發現對於的queue上麼有消費者,那麼這條訊息不會放入佇列中。當與訊息routeKey關聯的所有queue(一個或者多個)都沒有消費者時,該訊息會通過basic.return方法返還給生產者。

  概括來說,mandatory標誌告訴伺服器至少將該訊息route到一個佇列中,否則將訊息返還給生產者;immediate標誌告訴伺服器如果該訊息關聯的queue上有消費者,則馬上將訊息投遞給它,如果所有queue都沒有消費者,直接把訊息返還給生產者,不用將訊息入佇列等待消費者了。

  在RabbitMQ3.0以後的版本里,去掉了immediate引數的支援,傳送帶immediate標記的publish會返回如下錯誤:
    “{amqp_error,not_implemented,“immediate=true”,‘basic.publish’}”

  為什麼移除immediate標記,參見如下版本變化描述:

  immediate標記會影響映象佇列效能,增加程式碼複雜性,並建議採用“TTL”和“DLX”等方式替代。

  -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

  生產者在傳送訊息時不設定mandatory 引數,那麼訊息達到路由器後匹配不到相應的佇列後訊息將會丟失。
  設定了mandatory 引數,那麼需要新增ReturnListener的程式設計邏輯。
  如果既不想複雜化生產者的程式設計邏輯,又不想訊息丟失,那麼可以使用備份交換器。

  顧名思義 備份交換器就是當第一個交換器未能有效匹配到佇列時,路由到備份交換器,再由備份交換器區匹配佇列

備份交換器需要注意的是:

  如果交換器的名字之前宣告過了在RabbitMQ中已經存在,便不可修改新增引數,修改會報錯。
  解決方案:換個交換器的名字或者刪除之前的交換器
注意點:
  如果設定的備份交換器不存在,客戶端和RabbitMQ 服務端都不會有異常出現,此時訊息會丟失。
  如果備份交換器沒有繫結任何佇列,客戶端和RabbitMQ 服務端都不會有異常出現,此時訊息會丟失。
  如果備份交換器沒有任何匹配的佇列,客戶端和RabbitMQ 服務端都不會有異常出現,此時訊息會丟失。
  如果備份交換器和mandatory 引數一起使用,那麼mandatory 引數無效( 不會返還給生產者 )。即備份交換機優先於mandatory