【发布时间】:2015-08-02 19:49:57
【问题描述】:
在我们的一个项目中,当我们使用具有大量消息(1M 或更多)的调度工具(在 ActiveMQ 配置中启用 schedulerSupport)时,我们正遭受 ActiveMQ 性能下降的困扰。该项目基于 Spring,我们也在使用 Camel 进行路线管理。
我们的路线配置如下:
- 生产者 P 每秒产生 800 条消息,并通过非持久 ActiveMQ 队列 Q 发送它们
- 消费者 Cq 根据以下规则处理来自 Q 的消息:对于每条消息,它验证是否可以立即处理该消息(每条消息都有一个时间窗口属性来定义它)。如果可能,Cq 将消息转发到限制队列 T;如果不是,Cq 将消息转发到支持队列 S
- 消费者 Cs 处理来自 S 的消息并根据其时间窗口调度消息(使用以下语句设置 ActiveMQ 属性
ScheduledMessage.AMQ_SCHEDULED_DELAY:message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, <delay>);)其中<delay>根据消息时间进行评估-窗口 - 当调度消息从 ActiveMQ 调度区域唤醒时,它会被转发到 Throttling queue T
- 消费者 Ct 使用第三方组件(通过 TCP 连接)处理来自 T 的消息
当 P 生成用于立即处理的消息(即,没有时间窗口)时,即使有大量消息(1M 或更多),系统也能很好地执行:监控队列我们可以看到它们几乎是空的(没有消息在任何队列)。
当 P 为延迟处理(即使用时间窗口)生成消息时,我们会看到以下行为:
- 我们在所有队列(Q 和 S)中都有待处理的消息,而我们希望它们仅在队列 S 上待处理
- 当 S 中调度的消息唤醒时,它们会移动到 T 队列:这些消息根据节流配置进行处理(1K 消息/秒)
- 在 Q 和 S 中仍待处理的消息向 T 移动的速度非常缓慢(大约 50 条消息/秒)
- 如果我们在处理完所有宝贵的消息之后(再次使用生产者 P)尝试第二轮消息(没有时间窗口),我们仍然以 50 条消息/秒的速度发送消息,即使在在这种情况下,我们根本没有使用预定区域
问题摘要
- ActiveMQ 版本:5.9.0(配置最大内存限制为 3GB)
- 骆驼版:2.15.1
- 春季版:4.1.3.RELEASE
- 1 条消息的平均尺寸:4.5KiB
- 关键路线:
- Q -> S(预定区域)-> T
- Q -> T(使用预定区域后)
- 不使用调度程序:在 1M 消息内,我们可以轻松处理 1K 消息/秒(限制取决于 Camel Throttling 队列)
- 使用调度器:在 1M 条消息内,我们每秒处理 50 条消息
- 监控 CPU 和内存使用情况,我们无法发现任何问题:从 2% 到 5% 的 CPU 使用率,我们从未出现内存不足(Java GC 似乎也可以正常工作)
- 硬件(基于 VMWare 虚拟化):
- CPU:24 个 vCPU 映射到 24 个真正的“Intel(R) Xeon(R) CPU E5-2680 v3 @ 2.50GHz”CPU
- 内存:31744MB
提前感谢您的帮助,
爱神
【问题讨论】:
标签: java performance apache-camel activemq