Java 使用ActiveMQ调度程序时出现性能下降问题
在我们的一个项目中,当我们使用具有大量消息(1M或更多)的调度工具(在ActiveMQ配置中启用schedulerSupport)时,我们会遇到ActiveMQ性能下降的问题。该项目是基于Spring的,我们也在使用Camel进行路线管理 我们的路线配置如下:Java 使用ActiveMQ调度程序时出现性能下降问题,java,performance,apache-camel,activemq,Java,Performance,Apache Camel,Activemq,在我们的一个项目中,当我们使用具有大量消息(1M或更多)的调度工具(在ActiveMQ配置中启用schedulerSupport)时,我们会遇到ActiveMQ性能下降的问题。该项目是基于Spring的,我们也在使用Camel进行路线管理 我们的路线配置如下: 生产者P每秒生成800条消息,并通过非持久性ActiveMQ队列Q发送它们 消费者Cq根据以下规则处理来自Q的消息:对于每条消息,它验证消息是否可以立即处理(每条消息都有一个时间窗口属性来定义)。如果可能,Cq将消息转发到节流队列T;如
- 生产者P每秒生成800条消息,并通过非持久性ActiveMQ队列Q发送它们
- 消费者Cq根据以下规则处理来自Q的消息:对于每条消息,它验证消息是否可以立即处理(每条消息都有一个时间窗口属性来定义)。如果可能,Cq将消息转发到节流队列T;如果不是,Cq将消息转发到支持队列s中
- 使用者Cs处理来自S的消息,并根据其时间窗口对消息进行调度(使用以下语句设置ActiveMQ属性
:ScheduledMessage.AMQ_SCHEDULED_DELAY
)其中,message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY,);
根据消息时间窗口进行评估 - 当计划消息从ActiveMQ计划区域唤醒时,它被转发到限制队列T
- 消费者Ct使用第三方组件(通过TCP连接)处理来自T的消息
- 我们在所有队列(Q和S)中都有挂起的消息,而我们希望它们只在队列S上挂起
- 当在S中调度的消息唤醒时,它们移动到T队列:这些消息根据限制配置(1K消息/秒)进行处理
- Q和S中仍挂起的消息非常缓慢地移动到T(大约50条消息/秒)
- 如果我们在处理完所有宝贵的消息后(再次使用producer P)尝试第二轮消息(没有时间窗口),我们仍然以每秒50条消息的速度发送消息,即使在这种情况下,我们根本不使用计划区域
- ActiveMQ版本:5.9.0(配置3GB最大内存限制)
- 驼峰版本:2.15.1
- Spring版本:4.1.3.0版本
- 1条消息的平均尺寸:4.5KiB
- 关键路线:
- Q->S(计划区域)->T
- Q->T(使用计划区域后)
- 不使用调度程序:在1M消息内,我们可以轻松处理1K消息/秒(限制取决于骆驼节流队列)
- 使用调度程序:在1M条消息中,我们每秒处理50条消息
- 监控CPU和内存使用情况,我们无法发现任何问题:CPU使用率从2%到5%,而且我们从不耗尽内存(Java GC似乎也可以正常工作)
- 硬件(基于VMWare的虚拟化):
- CPU:24个VCPU映射到24个真正的“英特尔(R)至强(R)CPU E5-2680 v3@2.50GHz”CPU上
- 内存:31744MB
5.4版的ErosActiveMQ在ActiveMQ消息代理ActiveMQ.apache.org/delay-and-schedule-message-delivery.html中内置了一个可选的持久性调度程序 因此,为了提高性能,请尝试将下面的代码添加到
ActiveMQConnectionFactory上的brokerURL
例如:
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616?jms.copyMessageOnSend=false&jms.dispatchAsync=true&jms.useAsyncSend=true");
看看