我们有一个项目使用Spring-AMQP来使用来自RabbitMQ代理的消息。我们希望增加消费方面的并发性,以便多个工作线程可以并行处理消息。我首先阅读了原生RabbitMQ客户端的文档,并引导我使用单个消费者的设计,以及预取计数> 1控制并行性。直接使用RabbitMQ客户端,这似乎很自然。 handleDelivery
的{{1}}方法可以生成一个新的DefaultConsumer
来完成工作并在工作结束时确认消息。预取计数有效地控制了消费者产生的Runnable
的最大数量。
然而,这种设计似乎不适用于Spring-AMQP世界。在Runnable
中,对于每个AMQP使用者,所有消息都被传递到单个SimpleMessageListenerContainer
,并且单个线程将来自BlockingQueueConsumer
阻塞队列的消息传递到{{ 1}}。即使BlockingQueueConsumer
支持MessageListener
,SimpleMessageListenerContainer
也仅用于为每个消费者运行一个任务。因此,要并行处理多个消息,必须使用多个消费者。
这引出了一些关于Spring-AMQP并行性的问题。首先,我的初始设计是单个消费者和高预取计数是实现AMQP并行性的有效方法吗?如果是这样,为什么Spring-AMQP避开了这种设计,转而采用每个消费者的线程设计呢?是否可以自定义Spring-AMQP以实现单用户并行化?
答案 0 :(得分:1)
Spring AMQP是针对早期版本的兔子客户端库设计的,每个连接只有一个线程。
DefaultConsumer的handleDelivery方法可以生成一个新的Runnable,它可以完成工作并在工作结束时确认消息。
除了简单地增加concurrentConsumers
之外,这并没有真正为你买单 - 唯一的区别是每个线程都有一个消费者,但那里没有很多开销。
然而,您可以使用ChannelAwareMessageListener
执行所需操作并将acknowledgeMode设置为MANUAL
- 然后您的侦听器负责处理消息。
在2.0(明年)中,我们将有一个替代的侦听器容器,它将直接在客户端库线程上调用侦听器。但是,这是相当多的工作。 This (closed) pull request has an initial PoC但它还不是一个功能齐全的容器。