消息隊列中消息消費失敗后的處理機制


RocketMQ 中的機制

RocketMQ 中,消息消費結果的返回值有2個:ConsumeConcurrentlyStatus.CONSUME_SUCCESS 和 ConsumeConcurrentlyStatus.RECONSUME_LATER。
前者為消費成功,後者表示消費失敗。消費失敗后,RocketMQ會在特定時間間隔后進行重試,重試次數越多,時間間隔越長。

默認最多可以重試16次,每次重試的時間間隔為:

messageDelayLevel=1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h

RabbitMQ 中的機制

RabbitMQ 中,消息消費確認模式有如下3種:

  • AcknowledgeMode.NONE:不確認
  • AcknowledgeMode.AUTO:自動確認
  • AcknowledgeMode.MANUAL:手動確認

在Spring Boot中配置消費確認模式的配置:

spring.rabbitmq.listener.simple.acknowledge-mode=manual

手動確認模式中,如果消息消費失敗,可以選擇是否將消息重新放入隊列。
默認的確認模式為自動確認,如果消息消費的方法執行完成而未拋出異常,則會自動確認該消息消費成功;若拋出異常,則會自動確認消費失敗,此時消息會重新回到隊列中(按默認配置)。

消息消費失敗后如果重新放入隊列,RabbitMQ會立刻將消息重新推送給消費者,而沒有延遲推送的機制。
此時很可能會出現一直失敗並拋出異常的情況,浪費了資源,並導致日志爆滿,並淹沒最初幾條有用的異常日志信息(Java中如果多次拋出同樣的異常,打印日志時會省略部分異常堆棧)。

因此為了方便查看完整的異常堆棧,進程錯誤排查,建議在RabbitMQ消息消費失敗時,不要無限次的放回隊列。此時有以下兩種場景:

手動確認模式下

消費失敗時,不將其重新放入隊列(確認重試也不會成功的情形),打印錯誤信息后,通知相關人員,人工介入處理。

自動確認模式下

在Spring Boot RabbitMQ中,可以通過以下幾個配置參數,來調節消息消費失敗時,消息重新投遞的策略:

# 是否開啟消費者重試(為false時關閉消費者重試)
spring.rabbitmq.listener.simple.retry.enabled=true
# 最大重試重新投遞消息次數
spring.rabbitmq.listener.simple.retry.max-attempts=3
# 重試重新投遞消息的間隔時間(單位毫秒)
spring.rabbitmq.listener.simple.retry.initial-interval=5000ms
#重試次數超過上面的設置之后,是否丟棄(消費者listener拋出異常,是否重回隊列(默認true:重回隊列,false:不重回隊列(可結合死信交換機))
spring.rabbitmq.listener.simple.default-requeue-rejected=false

參考文檔

  1. RocketMQ消費消息失敗的處理辦法
  2. RabbitMQ的消息確認機制
  3. RabbitMQ與Spring、SpringBoot整合時的坑及注意點


免責聲明!

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



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