选择容器
版本 2.0 引入了 DirectMessageListenerContainer
(DMLC)。在此之前,只有 SimpleMessageListenerContainer
(SMLC)可用。SMLC 使用一个内部队列和每个消费者专用的线程。如果容器配置为监听多个队列,则使用相同的消费者线程来处理所有队列。并发性由 concurrentConsumers
和其他属性控制。当消息从 RabbitMQ 客户端到达时,客户端线程通过队列将它们交给消费者线程。这种架构是必需的,因为在早期版本的 RabbitMQ 客户端中,无法实现多个并发交付。较新版本的客户端采用了修订的线程模型,现在可以支持并发性。这使得 DMLC 的引入成为可能,其中监听器现在直接在 RabbitMQ 客户端线程上调用。因此,它的架构实际上比 SMLC 更“简单”。然而,这种方法有一些限制,并且 SMLC 的某些功能在 DMLC 中不可用。此外,并发性由 consumersPerQueue
(以及客户端库的线程池)控制。此容器不支持 concurrentConsumers
及相关属性。
以下功能在 SMLC 中可用,但在 DMLC 中不可用:
-
batchSize
:使用 SMLC 时,你可以设置此参数来控制在一个事务中传递多少条消息,或者减少确认(ack)的次数,但这可能会导致在失败后重复传递的次数增加。(DMLC 确实有messagesPerAck
参数,你可以用它来减少确认次数,这与 SMLC 的batchSize
类似,但它不能用于事务——每条消息都是在单独的事务中传递和确认的)。 -
consumerBatchEnabled
:启用消费者中离散消息的批处理;更多信息请参见消息监听器容器配置。 -
maxConcurrentConsumers
和消费者扩展间隔或触发器——DMLC 中没有自动扩展功能。然而,它允许你通过编程方式更改consumersPerQueue
属性,消费者会相应地调整。
然而,DMLC 相比 SMLC 具有以下优势:
-
运行时添加和移除队列更加高效。使用 SMLC 时,整个消费者线程会重启(所有消费者被取消并重新创建)。而使用 DMLC 时,未受影响的消费者不会被取消。
-
避免了 RabbitMQ Client 线程和消费者线程之间的上下文切换。
-
线程在消费者之间共享,而不是像 SMLC 那样为每个消费者分配一个专用线程。不过,请参阅线程与异步消费者中关于连接工厂配置的重要说明。
请参阅 消息监听器容器配置 以了解哪些配置属性适用于每个容器。