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