當(dāng)消費(fèi)者出現(xiàn)異常后,消息會不斷requeue(重入隊(duì))到隊(duì)列,再重新發(fā)送給消費(fèi)者。如果消費(fèi)者再次執(zhí)行依然出錯,消息會再次requeue到隊(duì)列,再次投遞,直到消息處理成功為止。
極端情況就是消費(fèi)者一直無法執(zhí)行成功,那么消息requeue就會無限循環(huán),導(dǎo)致mq的消息處理飆升,帶來不必要的壓力:

當(dāng)然,上述極端情況發(fā)生的概率還是非常低的,不過不怕一萬就怕萬一。為了應(yīng)對上述情況Spring又提供了消費(fèi)者失敗重試機(jī)制:在消費(fèi)者出現(xiàn)異常時利用本地重試,而不是無限制的requeue到mq隊(duì)列。
修改consumer服務(wù)的application.yml文件,添加內(nèi)容:
spring:
rabbitmq:
listener:
simple:
retry:
enabled: true # 開啟消費(fèi)者失敗重試
initial-interval: 1000ms # 初識的失敗等待時長為1秒
multiplier: 1 # 失敗的等待時長倍數(shù),下次等待時長 = multiplier * last-interval
max-attempts: 3 # 最大重試次數(shù)
stateless: true # true無狀態(tài);false有狀態(tài)。如果業(yè)務(wù)中包含事務(wù),這里改為false
重啟consumer服務(wù),重復(fù)之前的測試。可以發(fā)現(xiàn):
- 消費(fèi)者在失敗后消息沒有重新回到MQ無限重新投遞,而是在本地重試了3次
- 本地重試3次以后,拋出了AmqpRejectAndDontRequeueException異常。查看RabbitMQ控制臺,發(fā)現(xiàn)消息被刪除了,說明最后SpringAMQP返回的是reject
結(jié)論:
- 開啟本地重試時,消息處理過程中拋出異常,不會requeue到隊(duì)列,而是在消費(fèi)者本地重試
- 重試達(dá)到最大次數(shù)后,Spring會返回reject,消息會被丟棄
如果覺得有收獲,歡迎點(diǎn)贊和評論,更多知識,請點(diǎn)擊關(guān)注查看我的主頁信息哦~