rabbitMQ處理消息隊列時的自動應答機制淺述

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?原創者:文思

網絡資料(基本方向):

1:當出現異常時,我們需要把這個消息回滾到消息隊列要么拋棄此消息:

2:經過開發中的實際測試,當讓消息回滾到消息隊列時,這條消息不會回到隊列尾部,而是仍是在隊列頭部,這時消費者會立馬又接收到這條消息,進行處理,接著拋出異常,進行回滾,如此反復進行。這種情況會導致消息隊列處理出現阻塞,消息堆積,導致正常消息也無法運行。對于消息回滾到消息隊列,我們希望比較理想的方式時出現異常的消息到達消息隊列尾部,這樣既保證消息不會丟失,又保證了正常業務的進行,因此我們采取的解決方案是,將消息進行應答,這時消息隊列會刪除該消息,同時我們再次發送該消息到消息隊列,這時就實現了錯誤消息進行消息隊列尾部的方案。

實際應用:

在做jodconvert結合mq進行文檔異步轉換時,因在process函數中沒有捕獲convert方法(文檔轉換時的方法)中拋出的異常,導致mq的消費方(process函數)接收消息消費時失敗->返回隊列第一位->執行->消費失敗->返回隊列第一位,如此反復導致后續mq消息被阻塞無法接收執行,用catch()捕獲異常后,線應答成功,不會再次進入隊列執行,解決。

以此總結出mq自動應答的1個知識點:

Spring 與RabbitMq集成對消息的處理方式是默認自動應答(百度),但是mq消息消費與否的標志,網絡上百度出來的資料有些是錯誤的,現在通過程序來進行驗證和判斷,結論是:以process函數是否拋出異常或者異常是否被catch捕獲為標準,以下是程序推論:

process是消息放處理接收mq消息函數

在使用mq消息進行業務處理的過程中,也就是使用消息進行業務處理的時候(convertUrl = queueBusinessHandlerService.ms2pdfByQueueExternalUtil(inputUrl)),什么情況下系統會認為消息消費不會失敗,已經應答了呢,現在驗證異常依次上拋,在最外層捕獲(異常一定要依次通過throw拋出,否則程序就因為發生異常而中斷):

1

1.1

1.1.

1.1.1

1.1.1.1

從1.1.1.1依次上拋到1

然后在最外層捕獲:

通過命令行看日志可以看到,不會再執行那條mq記錄了,也就說明:

當convertUrl = queueBusinessHandlerService.ms2pdfByQueueExternalUtil(inputUrl)拋出異常時被catch捕獲,則process方法會認為消息消費成功,因為異常被捕獲了嘛,process程序體沒有中斷,執行完了,所以認為消費成功,進行了自動應答,即使業務函數處理失敗了,也不在會出現隊列中了。

如果需要對失敗的記錄進行處理,建議在catch{}中:

//手動進行應答channel.basicAck(msg.getMessageProperties().getDeliveryTag(), false);

//重新發送消息到隊列尾部channel.basicPublish(message.getMessageProperties().getReceivedExchange(),message.getMessageProperties().getReceivedRoutingKey(), MessageProperties.PERSISTENT_TEXT_PLAIN,JSON.toJSONBytes(new Object()));

不需要再次處理的就不用管了。


什么情況下算消費失敗,沒有應答成功呢,如果不在process中捕獲異常,或者在try{}catch(){}以外的地方發生異常,如下:

process中報了異常且沒有被catch捕獲,則process認為消息接收時出現錯誤,沒有消費成功,則自動返回到隊里第一位,再次重復執行:

.

反復回到隊列重復執行...

.

在使用spring boot時,默認的是自動應答,如果想手工應答,在application.propretes中:

spring.rabbitmq.listener.acknowledge-mode=manual

則:

mq順利執行完沒有報錯,但再次發送mq:

無法接收到新的mq消息。就需要在程序中進行手工消息應該操作:

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,993評論 19 139
  • 來源 RabbitMQ是用Erlang實現的一個高并發高可靠AMQP消息隊列服務器。支持消息的持久化、事務、擁塞控...
    jiangmo閱讀 10,409評論 2 34
  • 關于消息隊列,從前年開始斷斷續續看了些資料,想寫很久了,但一直沒騰出空,近來分別碰到幾個朋友聊這塊的技術選型,是時...
    預流閱讀 585,507評論 51 786
  • 有些東西,給你打開一扇窗的同時卻關閉了一道門,比如社交網絡 政治的功能之一是合理而恰當地處置謊言 時間這個東西,其...
    i圖紋系閱讀 1,515評論 0 14
  • 楔子 君問歸期未有期 我叫戚期, 親戚朋友們都說我的名字不好聽,取得很隨便,好像帶著某種欺騙似的。 而我卻...
    殤淺離閱讀 362評論 1 0