Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/372.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rabbit Mq java客户端并行消费_Java_Rabbitmq_Apache Camel - Fatal编程技术网

Rabbit Mq java客户端并行消费

Rabbit Mq java客户端并行消费,java,rabbitmq,apache-camel,Java,Rabbitmq,Apache Camel,我想并行处理来自rabbitMq队列的消息。队列配置为autoAck=false。我使用的是camel rabbitMQ支持,它支持threadPoolSize参数,但这没有达到预期效果。即使threadpoolsize=20,消息仍会在队列外连续处理 通过代码调试,我可以看到threadpoolsize参数用于创建ExecutorService,该服务用于传递到rabbit connectionfactory,如所述。在您进入rabbitConsumerWorkService之前,这一切看起来

我想并行处理来自rabbitMq队列的消息。队列配置为autoAck=false。我使用的是camel rabbitMQ支持,它支持threadPoolSize参数,但这没有达到预期效果。即使threadpoolsize=20,消息仍会在队列外连续处理

通过代码调试,我可以看到threadpoolsize参数用于创建ExecutorService,该服务用于传递到rabbit connectionfactory,如所述。在您进入rabbit
ConsumerWorkService
之前,这一切看起来都很好。在这里,消息以最大16条消息的块进行处理。一个块中的每条消息都被串行处理,如果还有更多的工作要做,执行器服务将与下一个块一起调用。下面是一段代码片段。通过使用executor服务,我看不出如何并行处理消息。executorservice一次只能执行一项工作

我错过了什么

private final class WorkPoolRunnable implements Runnable {

        public void run() {
            int size = MAX_RUNNABLE_BLOCK_SIZE;
            List<Runnable> block = new ArrayList<Runnable>(size);
            try {
                Channel key = ConsumerWorkService.this.workPool.nextWorkBlock(block, size);
                if (key == null) return; // nothing ready to run
                try {
                    for (Runnable runnable : block) {
                        runnable.run();
                    }
                } finally {
                    if (ConsumerWorkService.this.workPool.finishWorkBlock(key)) {
                        ConsumerWorkService.this.executor.execute(new WorkPoolRunnable());
                    }
                }
            } catch (RuntimeException e) {
                Thread.currentThread().interrupt();
            }
        }
private final类WorkPoolRunnable实现Runnable{
公开募捐{
int size=最大可运行块大小;
列表块=新的ArrayList(大小);
试一试{
通道密钥=ConsumerWorkService.this.workPool.nextWorkBlock(块,大小);
if(key==null)return;//没有准备好运行的内容
试一试{
for(可运行:块){
runnable.run();
}
}最后{
if(ConsumerWorkService.this.workPool.finishWorkBlock(键)){
ConsumerWorkService.this.executor.execute(新的WorkPoolRunnable());
}
}
}捕获(运行时异常e){
Thread.currentThread().interrupt();
}
}

RabbitMQ的文档对此并不十分清楚,但是,即使
ConsumerWorkService
正在使用线程池,该池似乎也无法并行处理消息:

每个通道都有自己的调度线程。对于每个通道一个使用者的最常见用例,这意味着使用者不会占用其他使用者。如果每个通道有多个使用者,请注意,长时间运行的使用者可能会占用对该通道上其他使用者的回调调度

()

本文档建议每个线程使用一个
通道
,事实上,如果您只需创建所需并发级别的
通道
,消息将在链接到这些通道的使用者之间发送

我已经用2个通道和消费者进行了测试:当队列中有2条消息时,每个消费者一次只选择一条消息。您提到的16条消息块似乎没有干扰,这是一件好事

事实上,Spring AMQP还创建了多个通道来同时处理消息。这是通过以下方式完成的:

  • 设置SimpleMessageListenerContainer.setConcurrentConsumers(…):
  • 并相应地设置
    CachingConnectionFactory.setChannelCacheSize(…)

我还测试了它是否正常工作。

如果您有一个
频道
实例,它将在您通过检查
ConsumerWorkService
正确发现的情况下连续调用其注册的使用者。有两种方法可以克服这一问题:

  • 使用多个通道,而不是一个
  • 使用单通道,但以特殊的方式实现使用者。他们应该只从队列中选取传入消息,并将其作为任务放入内部线程池

  • 您可以在中找到更多详细信息。

    您可以配置ConsumerWorkService以使用不同的块大小吗?嗨,克劳斯,我已经作为Fergus Nelson通过github对Camel rabbitmq组件进行了一些更改。我已经对RabbitMqConsumer进行了更改,以便为每个需要的concurant consumer设置一个通道。我将在ave已测试了所有内容。@mR_fr0g,据我所知,您已通过在Camel RabbitMQ组件中创建多个通道解决了此问题。您能否提供指向Jira票证的链接、请求并指定修复存在于哪个Camel版本中?