RMQ 消息確認機制
RabbitMQ 通過消息確認機制來保障消息從隊列到消費者的可靠傳遞,該機制主要分為兩種:
自動確認(Auto Acknowledge,autoACK):
在這種模式下,RabbitMQ 在將消息推送到消費者后立即將消息標(biāo)記為已確認。這意味著不管消費者是否成功處理了該消息,消息都會被從隊列中刪除。
這種模式可以提高吞吐量,但存在消息丟失的風(fēng)險,因為如果消費者在處理消息時失敗,消息已經(jīng)被刪除。手動確認(Manual Acknowledge):
在這種模式下,消費者在成功處理消息后,顯式地向 RabbitMQ 發(fā)送確認(ACK)信號。
如果消費者沒有發(fā)送 ACK 信號,消息會一直留在隊列中,直到被明確確認或者重新投遞(根據(jù)配置)。
為了保證消息的可靠性,一般優(yōu)先推薦使用手動確認模式。
問:隊列如何知道某個消費者已經(jīng)空閑,并且可以接受新的消息?
答:1. 在手動確認模式下,隊列正是通過消費者的 ACK 信號來判斷該消費者是否處于空閑狀態(tài),從而決定是否可以推送新的消息給該消費者。2. 而在自動確認模式下,由于不存在 ACK 信號。所以隊列不知道也不在乎消費者是否處于空閑,有消息就會推。這也是為什么雖然自動確認模式可以提高吞吐量,但我們通常更建議使用手動確認模式。
Spring AMQP 消息確認模式 vs RMQ 消息確認模式
當(dāng)我們在 Spring 框架下基于 Spring AMQP 使用 RMQ 時需要注意,Spring AMQP 框架定義的消息確認模式(參考:org.springframework.amqp.core.AcknowledgeMode 枚舉類)和RMQ官網(wǎng)定義的消息確認模式并不完全是一回事,需要區(qū)分看待。
Spring AMQP 的消息確認模式總共有三種:
-
NONE- 對應(yīng) RMQ 的 Auto Ack,即消費者無需 ack; -
MANUAL- 對應(yīng) RMQ 的 Manual Ack,需要開發(fā)者在代碼中明確發(fā)起 ack;
以使用@RabbitListener為例,如果采用手動確認模式,即@RabbitListener注解參數(shù)ackMode = "MANUAL",那么開發(fā)者需要在@RabbitListener注解的方法內(nèi)明確調(diào)用 ack; -
AUTO- 對應(yīng) RMQ 的 Manual Ack,Spring 框架會自動幫你調(diào)用 ack;
以使用@RabbitListener為例,AUTO是@RabbitListener默認采用的確認模式,框架會在@RabbitListener注解的方法正常返回時,自動調(diào)用ack,拋異常時自動調(diào)用nack。
當(dāng)你使用 Spring AMQP 的 basicConsume 方法傳入 autoAck = true 時,對應(yīng)的 Spring AMQP 確認模式是 NONE。