RabbitMQ 消息確認機制 以及 原理解析

  • 1、場景

  1. 當消息的投送方把消息投遞出去,殊不知道消息是否投遞成功了。若是消息投送方無論的話,勢必對系統的形成可靠性的影響。
  2. 但是若是要保證系統的可靠性,消息投靠方,如何知道消息是否投放成功了呢?
  3. 這個就須要消息的確認機制,咱們來看下rabbitMQ的消息去人機制是如何作的。

  • 2、原理:上圖

    

 

  • 3、原理解析

  1. 消息的確認分兩部分:rabbitMQ確認生產者投遞的消息 和 消費者確認 rabbitMQ服務器的消息

  2. 首先說RabbitMQ對生產者的確認,總共分爲兩種模式分別爲 同步模式異步模式

    (1)  同步模式分爲 單條消息確認批量確認

      ①  單條消息確認: channel.waitForConfirms() 普通發送方確認模式;消息到達交換器,就會返回true

      ②  批量消息確認: channel.waitForConfirmsOrDie()批量確認模式;使用同步方式等全部的消息發送以後纔會執行後面代碼,只要有一個消息未到達交換器就會拋出IOException異常。

    (2) 異步模式爲生產者 異步監聽消息確認

服務器

      異步監聽消息確認:channel.addConfirmListener()異步監聽發送方確認模式

異步

    3. 其次說下消費者對RabbitMQ 消息確認。總共分爲兩種方式 分別爲 手動確認 和 自動確認。

spa

      消費者收到的每一條消息都必須進行確認。消息確認後,RabbitMQ纔會從隊列刪除這條消息,RabbitMQ不會爲未確認的消息設置超時時間,它判斷此消息是否須要從新投遞給消費者的惟一依據是消費該消的消費者鏈接是否已經斷開。設計

    這麼設計的緣由是RabbitMQ容許消費者消費一條消息的時間能夠好久好久。

blog

    (1) 自動確認:隊列

  消費者在聲明隊列時,能夠指定autoAck參數,當autoAck=true時,一旦消費者接收到了消息,就視爲自動確認了消息。若是消費者在處理消息的過程當中,出了錯,就沒有什麼辦法從新處理這條消息,因此咱們不少時候,進程

須要在消息處理成功後,再確認消息,這就須要手動確認。

內存

  (2)  手動確認:同步

      

         ①當autoAck=false時,RabbitMQ會等待消費者顯式發回ack信號後才從內存(和磁盤,若是是持久化消息的話)中移去消息。不然,RabbitMQ會在隊列中消息被消費後當即刪除它。

it

 

         ②採用消息確認機制後,只要令autoAck=false,消費者就有足夠的時間處理消息(任務),不用擔憂處理消息過程當中消費者進程掛掉後消息丟失的問題,由於RabbitMQ會一直持有消息直到消費者顯式調用basicAck爲止。

 

  ③當autoAck=false時,對於RabbitMQ服務器端而言,隊列中的消息分紅了兩部分:一部分是等待投遞給消費者的消息;一部分是已經投遞給消費者,可是尚未收到消費者ack信號的消息。若是服務器端一直沒有收到消費

者的ack信號,而且消費此消息的消費者已經斷開鏈接,則服務器端會安排該消息從新進入隊列,等待投遞給下一個消費者(也可能仍是原來的那個消費者)。

 

   ④經過運行程序,啓動兩個消費者AB,均可以收到消息,可是其中有一個消費者A不會對消息進行確認,當把這個消費者A關閉後,消費者B又會收到原本發送給消費者A的消息。因此咱們通常使用手動確認的方法是,將消息的處理放在try/catch語句塊中,成功處理了,就給RabbitMQ一個確認應答,若是處理異常了,就在catch中,進行消息的拒絕

 

 

 

  • 若是有什麼不足歡迎討論!
相關文章
相關標籤/搜索