RabbitMQ(Java)多用户性能问题
我正在实现一个日常作业,该作业从MongoDB(大约30万个文档)获取数据,并为每个文档在RabbitMQ队列上发布消息。 另一方面,我有一些消费者在同一个队列中,理想情况下应该并行工作 一切正常,但没有我想象的那么多,特别是在消费者表现方面 以下是我声明队列的方式:RabbitMQ(Java)多用户性能问题,java,mongodb,rabbitmq,amqp,mongodb-java,Java,Mongodb,Rabbitmq,Amqp,Mongodb Java,我正在实现一个日常作业,该作业从MongoDB(大约30万个文档)获取数据,并为每个文档在RabbitMQ队列上发布消息。 另一方面,我有一些消费者在同一个队列中,理想情况下应该并行工作 一切正常,但没有我想象的那么多,特别是在消费者表现方面 以下是我声明队列的方式: rabbitMQ.getChannel().queueDeclare(QUEUE_NAME, true, false, false, null); 以下是发布的方式: rabbitMQ.getChannel().basicPub
rabbitMQ.getChannel().queueDeclare(QUEUE_NAME, true, false, false, null);
以下是发布的方式:
rabbitMQ.getChannel().basicPublish("", QUEUE_NAME, null, body.getBytes());
因此,用于声明队列的通道用于发布所有消息
这就是消费者在for循环中的实例化方式(总共10个,但可以是任意数量):
因此,我为每个消费者创建了一个新的渠道,并通过日志证实了这一点:
...
com.rabbitmq.client.impl.recovery.AutorecoveringChannel@bdd2027
com.rabbitmq.client.impl.recovery.AutorecoveringChannel@5d1b9c3d
com.rabbitmq.client.impl.recovery.AutorecoveringChannel@49a26d19
...
据我在RabbitMQ上的短暂经历所知,这应该保证调用所有消费者。
顺便说一下,消费者需要0.5到1.2秒来完成他们的任务。我刚刚发现只有3秒钟
我有两个单独的队列,我重复上面所说的两次(使用相同的RabbitMQ连接)
因此,我测试了为每个队列发布100条消息。它们都有10个qos=1的消费者
我没想到会有10/s的交付/消费性能,相反,我注意到:
- 实际值约为0.4和1.0
- 至少所有绑定到队列的消费者都收到了一条消息,但它看起来不像“公平调度”
- 消耗两个队列上的所有消息大约需要3分钟30秒
谢谢你的帮助 RabbitMQ通道和使用者的设置最终是正确的:因此每个使用者有一个通道 问题在于消费者调用同步方法来查找和更新MongoDB文档 这会延迟一些使用者的执行时间:即使最糟糕的是,我添加的使用者越多(考虑加快处理速度),得到的消息速率也越低 我已经将MongoDB部分移到了发布端,我不必关心同步,因为它是由一个发布者按顺序完成的。我的交付速率略有下降,但现在只有5个消费者,我很容易达到50-60/s的确认速率 经验教训:
- 为发布者创建单独的频道
- 为每个消费者创建单独的频道
- 让RabbitMQ为使用者管理线程(->您可以在主线程上实例化它们)
- (如果可能)停止发布,让队列有100%的时间与消费者打交道
- 为每个用户通道设置qos>1。但这实际上取决于您的场景和体系结构:您必须进行一些性能测试
- (1) 计算/估计交货时间
- (2) 计算/估计确认时间
- (3) 计算/估计消费者时间
- 服务质量=(1)+(2)+(3)/(3)
这将为您提供初始qos值,以便根据您的场景进行测试和调整。最终的目标是使所有可用的消费者都能100%利用率 您是否查看了使用消息的应用程序的堆栈跟踪?是否有10个线程正在读取RabbitMQ?这10个线程在做什么?我怀疑在应用程序逻辑中有什么东西阻塞了消费者。如果随着时间的推移查看一些堆栈跟踪,您应该会得到一个查找位置的提示。@Robmore仔细检查堆栈跟踪,我看到消费者为了查找和更新mongodb文档而相互竞争。事实上,如果我把这部分注释掉,我每秒可以消耗几十条消息。我现在正在重构代码,尝试在发布端移动db更新,让使用者只执行最简单的任务。在一个通道上只让一个客户端使用者在客户端中分派工作如何?
...
com.rabbitmq.client.impl.recovery.AutorecoveringChannel@bdd2027
com.rabbitmq.client.impl.recovery.AutorecoveringChannel@5d1b9c3d
com.rabbitmq.client.impl.recovery.AutorecoveringChannel@49a26d19
...