You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

ActiveMQ 5.9性能测试中Broker线程因锁未释放阻塞问题求助

嘿,我来帮你捋一捋这个棘手的问题——你的ActiveMQ 5.9搭配Camel 2.10.3在高负载测试下,Broker卡在连接关闭操作上,结合你提供的线程栈和日志,咱们可以精准定位问题根源,然后给出可行的解决办法:

核心问题拆解

先看你提供的线程信息:

  • 那个一直持锁不释放的线程(#5774):卡在TransportConnection.stop()方法里等待CountDownLatch,而且已经锁住了<0x000000050401eed0>这个全局对象
  • 500多个阻塞线程:全部在等待获取同一个<0x000000050401eed0>锁,卡死在processAddConnection步骤上

这就形成了一个死循环:一个异常断开的连接触发Broker的关闭操作,这个操作占用了连接处理的全局锁,但因为内部的CountDownLatch无法完成计数,导致锁一直不释放;而客户端因为连接断开开始反复重连,所有新的连接请求都被这个锁堵在外面,最终Broker彻底无法处理新连接

再结合日志细节:

Broker端首次报错:Transport Connection to: tcp://10.128.43.206:48747 failed: java.io.EOFException
客户端反复重连但随即断开:Transport (tcp://10.128.43.169:61616) failed, reason: java.io.IOException, attempting to automatically reconnect

这说明客户端连接是异常断开的,而Broker的连接关闭逻辑在这个场景下出了问题,导致锁阻塞。

可能的根源

  1. ActiveMQ 5.9的已知bug:这个版本是2013年的老版本,TransportConnection类在处理连接关闭时存在CountDownLatch计数异常的问题——当客户端突然断开,Broker尝试关闭连接时,内部的异步任务没有正确收尾,导致CountDownLatch一直处于等待状态,持锁不释放。后续版本(5.10+)已经修复了这个问题。
  2. 连接池与缓存配置的冲突:你用了默认配置的PooledConnectionFactory,缓存级别是CACHE_CONSUMER,每个节点最多10个并发消费者。在高负载下,这种配置会导致连接池频繁创建/销毁连接,再加上故障转移的重连机制,直接把Broker的连接处理能力压垮。
  3. Broker连接处理能力不足:虽然设置了maximumConnections=1000,但高负载下连接的创建/销毁速度远超Broker的处理能力,再加上锁阻塞的放大效应,最终导致连接队列彻底堵死。

解决方案建议

1. 优先升级ActiveMQ版本(最根治的方案)

ActiveMQ 5.9的连接处理逻辑存在明显缺陷,建议直接升级到5.15.x或更高的稳定版本。注意兼容性:Camel 2.10.3可以兼容到ActiveMQ 5.12,如果想更稳妥,可以同步把Camel升级到2.15+,这样能更好地适配新版本的ActiveMQ。

2. 调整客户端连接池配置

  • 修改缓存级别:如果你的消费者是长期运行的,把CACHE_CONSUMER改成CACHE_CONNECTIONCACHE_SESSION,减少连接的频繁创建/销毁
  • 优化连接池参数:设置maxConnections(建议和Broker的maximumConnections匹配)、idleTimeout(比如300000毫秒),避免连接池里的连接频繁超时断开
  • 限制重连频率:在客户端的故障转移URL里添加initialReconnectDelay=1000&maxReconnectDelay=5000,避免短时间内大量重连请求冲击Broker

3. 优化Broker的连接处理配置

  • 关闭异步连接关闭:在Broker的TCP连接URL里添加transport.closeAsync=false(默认是异步关闭,容易导致CountDownLatch等待),改为同步关闭,确保连接关闭时所有内部任务都能完成
  • 提升线程池大小:修改activemq.xml里的transportConnectorthreadPoolSize参数,比如设置为200,提升连接处理的并发能力
  • 优化无效连接清理:确保AbstractInactivityMonitorkeepAliveInterval设置合理(比如30000毫秒),及时清理无效连接,减少不必要的关闭操作

4. 临时应急方案(如果暂时无法升级)

  • 手动重启Broker:能快速释放被阻塞的锁和线程,但这只是临时解决,无法根治问题
  • 降低客户端负载:减少每个客户端节点的并发消费者数量,或者限制客户端的连接池大小,降低Broker的连接处理压力

内容的提问来源于stack exchange,提问作者Giulio Pulina

火山引擎 最新活动