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