Choosing a Container

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

Version 2.0 introduced the DirectMessageListenerContainer (DMLC). Previously, only the SimpleMessageListenerContainer (SMLC) was available. The SMLC uses an internal queue and a dedicated thread for each consumer. If a container is configured to listen to multiple queues, the same consumer thread is used to process all the queues. Concurrency is controlled by concurrentConsumers and other properties. As messages arrive from the RabbitMQ client, the client thread hands them off to the consumer thread through the queue. This architecture was required because, in early versions of the RabbitMQ client, multiple concurrent deliveries were not possible. Newer versions of the client have a revised threading model and can now support concurrency. This has allowed the introduction of the DMLC where the listener is now invoked directly on the RabbitMQ Client thread. Its architecture is, therefore, actually “simpler” than the SMLC. However, there are some limitations with this approach, and certain features of the SMLC are not available with the DMLC. Also, concurrency is controlled by consumersPerQueue (and the client library’s thread pool). The concurrentConsumers and associated properties are not available with this container.

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

The following features are available with the SMLC but not the DMLC:

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

  • batchSize: With the SMLC, you can set this to control how many messages are delivered in a transaction or to reduce the number of acks, but it may cause the number of duplicate deliveries to increase after a failure. (The DMLC does have messagesPerAck, which you can use to reduce the acks, the same as with batchSize and the SMLC, but it cannot be used with transactions — each message is delivered and ack’d in a separate transaction).

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

  • consumerBatchEnabled: enables batching of discrete messages in the consumer; see Message Listener Container Configuration for more information.

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

  • maxConcurrentConsumers and consumer scaling intervals or triggers — there is no auto-scaling in the DMLC. It does, however, let you programmatically change the consumersPerQueue property and the consumers are adjusted accordingly.

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

However, the DMLC has the following benefits over the SMLC:

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

  • Adding and removing queues at runtime is more efficient. With the SMLC, the entire consumer thread is restarted (all consumers canceled and re-created). With the DMLC, unaffected consumers are not canceled.

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

  • The context switch between the RabbitMQ Client thread and the consumer thread is avoided.

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

  • Threads are shared across consumers rather than having a dedicated thread for each consumer in the SMLC. However, see the IMPORTANT note about the connection factory configuration in Threading and Asynchronous Consumers.

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

See Message Listener Container Configuration for information about which configuration properties apply to each container.