Choosing a Container

版本 2.0 引入了 DirectMessageListenerContainer (DMLC)。以前,只有 SimpleMessageListenerContainer (SMLC) 可用。SMLC 为每个消费者使用一个内部队列和一个专用线程。如果容器配置为监听多个队列,则使用同一个消费者线程来处理所有队列。并发性由 concurrentConsumers 和其他属性控制。当消息从 RabbitMQ 客户端到达时,客户端线程通过队列将它们传递给消费者线程。需要这种架构,因为在 RabbitMQ 客户端的早期版本中,无法进行多并发传递。客户端的更新版本具有修改过的线程模型,现在支持并发性。这允许引入 DMLC,其中现在直接在 RabbitMQ 客户端线程上调用监听器。因此,其架构实际上比 SMLC“更简单”。但是,这种方法有一些限制,而 SMLC 的某些功能不能与 DMLC 配合使用。此外,并发性由 consumersPerQueue(和客户端库的线程池)控制。concurrentConsumers 及其关联属性不可与此容器配合使用。

以下功能可与 SMLC 配合使用,但不能与 DMLC 配合使用:

  • batchSize:通过 SMLC,你可以设置此选项来控制在一个交易中传递的消息数量或减少确认消息的数量,但它可能会导致故障后重复传递消息的数量增加。(DMLC 具有 messagesPerAck,你可以使用它来减少确认消息的数量,与 batchSize 和 SMLC 相同,但是它不能与交易一起使用——每条消息在单独的交易中被传递并得到确认。)。

  • consumerBatchEnabled:在使用者中启用离散消息的批处理;有关详细信息,请参见 Message Listener Container Configuration

  • maxConcurrentConsumers 及消费者缩放间隔或触发器——DMLC 中不存在自动缩放。但是,它确实让你可以以编程方式更改 consumersPerQueue 属性,并且会相应地调整消费者。

但是,DMLC 相对于 SMLC 具有以下好处:

  • 在运行时添加和移除队列效率更高。通过 SMLC,整个消费者线程重新启动(所有消费者取消并重新创建)。使用 DMLC 时,不受影响的消费者不会被取消。

  • 避免了 RabbitMQ 客户端线程和消费者线程之间的上下文切换。

  • 线程在使用者之间共享,而不是为 SMLC 中的每个使用者提供一个专用线程。但是,请参见 Threading and Asynchronous Consumers 中有关连接工厂配置的重要说明。

请参阅 Message Listener Container Configuration以了解哪些配置属性应用于每个容器。