在 Spring 框架中使用 @RabbitListener
时,其背后与 RMQ 服务的交互流程如下:
连接建立:
当应用启动时,Spring AMQP 自动配置(Auto Configuration)机制会根据配置创建一个连接工厂(Connection Factory),并与 RabbitMQ 服务器建立连接。从 RMQ 服务的视角看,就是建立了一个Connection
。注册消费者&订阅
- Spring 应用启动时,扫描带有
@RabbitListener
注解的方法; - Spring AMQP 为每个注解的方法注册一个或多个消费者(默认 1 个,可以通过注解的
concurrency
参数配置多个消费者); -
SimpleMessageListenerContainer
在内部创建相应数量的消费者线程; - 这些消费者线程在启动时,会从
ConnectionFactory
获取Channel
,通过Channel
向 RabbitMQ 服务发送Basic Consume
命令,这一操作告诉 RabbitMQ 服务,这些消费者线程订阅了指定的队列,并准备接收消息; - 此时 RabbitMQ 服务视角正式得知这些消费者的存在,每个消费者对应一个
Channel
。
- 消息获取(Message Fetching):
- RabbitMQ 将消息推送(push)给消费者,消费者通过
basicDeliver
方法接收消息。这是一个被动的过程,消费者等待消息被推送,而不是主动拉取。
basicDeliver
方法是 RabbitMQ 客户端库(如 Java 中的 amqp-client 库)用来处理服务器推送消息的一个回调方法。
- 消息处理:
一旦消息被推送到消费者,Spring 最终会调用相应的@RabbitListener
注解的方法来处理消息,例如:
@RabbitListener(queues = "yourQueueName")
public void handleMessage(String message) {
// 处理消息的逻辑
System.out.println("Received message: " + message);
}
Spring AMQP 框架实现了一个
ChannelAwareMessageListener
,它内部处理basicDeliver
方法,并将消息传递给相应的@RabbitListener
注解的方法。
在默认的自动确认模式下(auto-acknowledge),Spring 会在 @RabbitListener 方法成功返回后自动确认消息。
你可能会困惑:诶?RMQ 的自动确认模式不是不需要客户端返回 ACK 吗?
注意:这里说的自动确认模式,指的是 Spring 框架定义的确认模式(参考:org.springframework.amqp.core.AcknowledgeMode
枚举类),需要将其与 RMQ 的 ACK 模式进行区分。
Spring 中确认模式的自动确认(AUTO
)对应到 RMQ 的 ACK 模式其实是手工确认模式(Manual Ack),只是 Spring 框架会在@RabbitListener
方法成功返回后自动调用 ACK 方法给 RMQ 服务发送消息确认。
RMQ ACK 模式 中的 Auto Ack 对应到 Spring 框架的确认模式是NONE
—— 无需确认。
更多关于消息确认模式的内容,可以阅读:RMQ 的 autoACK 自动消息确认是什么?
如果配置了手动确认模式,开发者需要显式地调用确认方法,如 basicAck
或 basicNack
。