具有预取的Spring AMQP单一消费者并行性

时间:2016-05-03 22:47:13

标签: spring multithreading rabbitmq spring-amqp

我们有一个项目使用Spring-AMQP来使用来自RabbitMQ代理的消息。我们希望增加消费方面的并发性,以便多个工作线程可以并行处理消息。我首先阅读了原生RabbitMQ客户端的文档,并引导我使用单个消费者的设计,以及预取计数> 1控制并行性。直接使用RabbitMQ客户端,这似乎很自然。 handleDelivery的{​​{1}}方法可以生成一个新的DefaultConsumer来完成工作并在工作结束时确认消息。预取计数有效地控制了消费者产生的Runnable的最大数量。

然而,这种设计似乎不适用于Spring-AMQP世界。在Runnable中,对于每个AMQP使用者,所有消息都被传递到单个SimpleMessageListenerContainer,并且单个线程将来自BlockingQueueConsumer阻塞队列的消息传递到{{ 1}}。即使BlockingQueueConsumer支持MessageListenerSimpleMessageListenerContainer也仅用于为每个消费者运行一个任务。因此,要并行处理多个消息,必须使用多个消费者。

这引出了一些关于Spring-AMQP并行性的问题。首先,我的初始设计是单个消费者和高预取计数是实现AMQP并行性的有效方法吗?如果是这样,为什么Spring-AMQP避开了这种设计,转而采用每个消费者的线程设计呢?是否可以自定义Spring-AMQP以实现单用户并行化?

1 个答案:

答案 0 :(得分:1)

Spring AMQP是针对早期版本的兔子客户端库设计的,每个连接只有一个线程。

  

DefaultConsumer的handleDelivery方法可以生成一个新的Runnable,它可以完成工作并在工作结束时确认消息。

除了简单地增加concurrentConsumers之外,这并没有真正为你买单 - 唯一的区别是每个线程都有一个消费者,但那里没有很多开销。

然而,您可以使用ChannelAwareMessageListener执行所需操作并将acknowledgeMode设置为MANUAL - 然后您的侦听器负责处理消息。

在2.0(明年)中,我们将有一个替代的侦听器容器,它将直接在客户端库线程上调用侦听器。但是,这是相当多的工作。 This (closed) pull request has an initial PoC但它还不是一个功能齐全的容器。