跳到主要内容
版本:4.1.1

选择容器

Doubao 中英对照 Choosing a Container

2.0 版引入了 DirectMessageListenerContainer(DMLC)。此前,只有 SimpleMessageListenerContainer(SMLC)可用。SMLC 为每个消费者使用一个内部队列和一个专用线程。如果一个容器被配置为监听多个队列,则用同一个消费者线程处理所有队列。并发度由 concurrentConsumers 和其他属性控制。当消息从 RabbitMQ 客户端到达时,客户端线程通过队列把它们转交给消费者线程。这种架构在当时是必要的,因为在 RabbitMQ 客户端的早期版本中,无法进行多个并发投递。较新版本的客户端有了修订后的线程模型,现在可以支持并发。这使得 DMLC 得以引入,现在监听器直接在 RabbitMQ 客户端线程上被调用。因此,它的架构实际上比 SMLC 更"简单"。然而,这种方式存在一些限制,SMLC 的某些特性在 DMLC 上不可用。此外,并发度由 consumersPerQueue(以及客户端库的线程池)控制。concurrentConsumers 及相关属性在此容器上不可用。

以下特性在 SMLC 上可用,但在 DMLC 上不可用:

  • batchSize:在 SMLC 上,你可以设置它来控制一个事务中投递多少条消息,或减少 ack 的次数,但它可能导致失败后重复投递的次数增加。(DMLC 确实有 messagesPerAck,你可以用它来减少 ack,就像 batchSize 和 SMLC 一样,但它不能与事务一起使用——每条消息都在单独的事务中投递并 ack)。
  • consumerBatchEnabled:启用消费者侧离散消息的批处理;更多信息请参阅消息监听容器配置。
  • maxConcurrentConsumers 以及消费者伸缩间隔或触发器——DMLC 中没有自动伸缩。不过,它允许你以编程方式修改 consumersPerQueue 属性,消费者会相应地调整。

不过,与 SMLC 相比,DMLC 具有以下优势:

  • 在运行时添加和移除队列更高效。使用 SMLC 时,整个消费者线程都会重启(所有消费者被取消并重新创建)。使用 DMLC 时,未受影响的消费者不会被取消。
  • 避免了 RabbitMQ 客户端线程与消费者线程之间的上下文切换。
  • 线程在各消费者之间共享,而不像 SMLC 那样为每个消费者配备专用线程。不过,请参阅线程与异步消费者中关于连接工厂配置的 IMPORTANT 注意事项。

有关哪些配置属性适用于哪个容器的信息,请参阅消息监听容器配置。