在 Spring 框架中使用 @RabbitListener
時,其背后與 RMQ 服務(wù)的交互流程如下:
連接建立:
當(dāng)應(yīng)用啟動時株茶,Spring AMQP 自動配置(Auto Configuration)機(jī)制會根據(jù)配置創(chuàng)建一個連接工廠(Connection Factory)母剥,并與 RabbitMQ 服務(wù)器建立連接锹漱。從 RMQ 服務(wù)的視角看玉罐,就是建立了一個Connection
蒿褂。注冊消費(fèi)者&訂閱
- Spring 應(yīng)用啟動時,掃描帶有
@RabbitListener
注解的方法蒋畜; - Spring AMQP 為每個注解的方法注冊一個或多個消費(fèi)者(默認(rèn) 1 個声畏,可以通過注解的
concurrency
參數(shù)配置多個消費(fèi)者); -
SimpleMessageListenerContainer
在內(nèi)部創(chuàng)建相應(yīng)數(shù)量的消費(fèi)者線程姻成; - 這些消費(fèi)者線程在啟動時插龄,會從
ConnectionFactory
獲取Channel
,通過Channel
向 RabbitMQ 服務(wù)發(fā)送Basic Consume
命令科展,這一操作告訴 RabbitMQ 服務(wù)均牢,這些消費(fèi)者線程訂閱了指定的隊列,并準(zhǔn)備接收消息才睹; - 此時 RabbitMQ 服務(wù)視角正式得知這些消費(fèi)者的存在徘跪,每個消費(fèi)者對應(yīng)一個
Channel
。
- 消息獲壬笆(Message Fetching):
- RabbitMQ 將消息推送(push)給消費(fèi)者真椿,消費(fèi)者通過
basicDeliver
方法接收消息。這是一個被動的過程乎澄,消費(fèi)者等待消息被推送突硝,而不是主動拉取。
basicDeliver
方法是 RabbitMQ 客戶端庫(如 Java 中的 amqp-client 庫)用來處理服務(wù)器推送消息的一個回調(diào)方法置济。
- 消息處理:
一旦消息被推送到消費(fèi)者解恰,Spring 最終會調(diào)用相應(yīng)的@RabbitListener
注解的方法來處理消息,例如:
@RabbitListener(queues = "yourQueueName")
public void handleMessage(String message) {
// 處理消息的邏輯
System.out.println("Received message: " + message);
}
Spring AMQP 框架實(shí)現(xiàn)了一個
ChannelAwareMessageListener
浙于,它內(nèi)部處理basicDeliver
方法护盈,并將消息傳遞給相應(yīng)的@RabbitListener
注解的方法。
在默認(rèn)的自動確認(rèn)模式下(auto-acknowledge)羞酗,Spring 會在 @RabbitListener 方法成功返回后自動確認(rèn)消息腐宋。
你可能會困惑:誒?RMQ 的自動確認(rèn)模式不是不需要客戶端返回 ACK 嗎檀轨?
注意:這里說的自動確認(rèn)模式胸竞,指的是 Spring 框架定義的確認(rèn)模式(參考:org.springframework.amqp.core.AcknowledgeMode
枚舉類),需要將其與 RMQ 的 ACK 模式進(jìn)行區(qū)分参萄。
Spring 中確認(rèn)模式的自動確認(rèn)(AUTO
)對應(yīng)到 RMQ 的 ACK 模式其實(shí)是手工確認(rèn)模式(Manual Ack),只是 Spring 框架會在@RabbitListener
方法成功返回后自動調(diào)用 ACK 方法給 RMQ 服務(wù)發(fā)送消息確認(rèn)卫枝。
RMQ ACK 模式 中的 Auto Ack 對應(yīng)到 Spring 框架的確認(rèn)模式是NONE
—— 無需確認(rèn)。
更多關(guān)于消息確認(rèn)模式的內(nèi)容讹挎,可以閱讀:RMQ 的 autoACK 自動消息確認(rèn)是什么校赤?
如果配置了手動確認(rèn)模式吆玖,開發(fā)者需要顯式地調(diào)用確認(rèn)方法,如 basicAck
或 basicNack
马篮。