RMQ 消息確認(rèn)機(jī)制
RabbitMQ 通過(guò)消息確認(rèn)機(jī)制來(lái)保障消息從隊(duì)列到消費(fèi)者的可靠傳遞坡疼,該機(jī)制主要分為兩種:
自動(dòng)確認(rèn)(Auto Acknowledge箕昭,autoACK):
在這種模式下誉简,RabbitMQ 在將消息推送到消費(fèi)者后立即將消息標(biāo)記為已確認(rèn)。這意味著不管消費(fèi)者是否成功處理了該消息盟广,消息都會(huì)被從隊(duì)列中刪除闷串。
這種模式可以提高吞吐量,但存在消息丟失的風(fēng)險(xiǎn)筋量,因?yàn)槿绻M(fèi)者在處理消息時(shí)失敗烹吵,消息已經(jīng)被刪除。手動(dòng)確認(rèn)(Manual Acknowledge):
在這種模式下桨武,消費(fèi)者在成功處理消息后肋拔,顯式地向 RabbitMQ 發(fā)送確認(rèn)(ACK)信號(hào)。
如果消費(fèi)者沒有發(fā)送 ACK 信號(hào)呀酸,消息會(huì)一直留在隊(duì)列中凉蜂,直到被明確確認(rèn)或者重新投遞(根據(jù)配置)。
為了保證消息的可靠性性誉,一般優(yōu)先推薦使用手動(dòng)確認(rèn)模式窿吩。
問(wèn):隊(duì)列如何知道某個(gè)消費(fèi)者已經(jīng)空閑,并且可以接受新的消息错览?
答:1. 在手動(dòng)確認(rèn)模式下纫雁,隊(duì)列正是通過(guò)消費(fèi)者的 ACK 信號(hào)來(lái)判斷該消費(fèi)者是否處于空閑狀態(tài),從而決定是否可以推送新的消息給該消費(fèi)者倾哺。2. 而在自動(dòng)確認(rèn)模式下轧邪,由于不存在 ACK 信號(hào)。所以隊(duì)列不知道也不在乎消費(fèi)者是否處于空閑羞海,有消息就會(huì)推忌愚。這也是為什么雖然自動(dòng)確認(rèn)模式可以提高吞吐量,但我們通常更建議使用手動(dòng)確認(rèn)模式却邓。
Spring AMQP 消息確認(rèn)模式 vs RMQ 消息確認(rèn)模式
當(dāng)我們?cè)?Spring 框架下基于 Spring AMQP 使用 RMQ 時(shí)需要注意硕糊,Spring AMQP 框架定義的消息確認(rèn)模式(參考:org.springframework.amqp.core.AcknowledgeMode
枚舉類)和RMQ官網(wǎng)定義的消息確認(rèn)模式并不完全是一回事,需要區(qū)分看待申尤。
Spring AMQP 的消息確認(rèn)模式總共有三種:
-
NONE
- 對(duì)應(yīng) RMQ 的 Auto Ack癌幕,即消費(fèi)者無(wú)需 ack衙耕; -
MANUAL
- 對(duì)應(yīng) RMQ 的 Manual Ack昧穿,需要開發(fā)者在代碼中明確發(fā)起 ack;
以使用@RabbitListener
為例橙喘,如果采用手動(dòng)確認(rèn)模式时鸵,即@RabbitListener
注解參數(shù)ackMode = "MANUAL"
,那么開發(fā)者需要在@RabbitListener
注解的方法內(nèi)明確調(diào)用 ack; -
AUTO
- 對(duì)應(yīng) RMQ 的 Manual Ack饰潜,Spring 框架會(huì)自動(dòng)幫你調(diào)用 ack初坠;
以使用@RabbitListener
為例,AUTO
是@RabbitListener
默認(rèn)采用的確認(rèn)模式彭雾,框架會(huì)在@RabbitListener
注解的方法正常返回時(shí)碟刺,自動(dòng)調(diào)用ack
,拋異常時(shí)自動(dòng)調(diào)用nack
薯酝。
當(dāng)你使用 Spring AMQP 的 basicConsume 方法傳入 autoAck = true 時(shí)半沽,對(duì)應(yīng)的 Spring AMQP 確認(rèn)模式是 NONE。