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


  • 一、場景

  1. 當消息的投送方把消息投遞出去,卻不知道消息是否投遞成功了。如果消息投送方不管的話,勢必對系統的造成可靠性的影響。
  2. 可是如果要保證系統的可靠性,消息投靠方,如何知道消息是否投放成功了呢?
  3. 這個就需要消息的確認機制,我們來看下rabbitMQ的消息去人機制是如何做的。

  • 二、原理:上圖

    

 

  • 三、原理解析

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

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

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

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

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

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

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

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

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

    這么設計的原因是RabbitMQ允許消費者消費一條消息的時間可以很久很久。

    (1) 自動確認:

  消費者在聲明隊列時,可以指定autoAck參數,當autoAck=true時,一旦消費者接收到了消息,就視為自動確認了消息。如果消費者在處理消息的過程中,出了錯,就沒有什么辦法重新處理這條消息,所以我們很多時候,

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

  (2)  手動確認:

      

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

 

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

 

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

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

 

   ④通過運行程序,啟動兩個消費者AB,都可以收到消息,但是其中有一個消費者A不會對消息進行確認,當把這個消費者A關閉后,消費者B又會收到本來發送給消費者A的消息。所以我們一般使用手動確認的方法是,將消息的處理放在try/catch語句塊中,成功處理了,就給RabbitMQ一個確認應答,如果處理異常了,就在catch中,進行消息的拒絕

 

 

 

  • 如果有什么不足歡迎討論!

 

 


免責聲明!

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



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