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的连接关闭逻辑在这个场景下出了问题,导致锁阻塞。
可能的根源
- ActiveMQ 5.9的已知bug:这个版本是2013年的老版本,
TransportConnection类在处理连接关闭时存在CountDownLatch计数异常的问题——当客户端突然断开,Broker尝试关闭连接时,内部的异步任务没有正确收尾,导致CountDownLatch一直处于等待状态,持锁不释放。后续版本(5.10+)已经修复了这个问题。 - 连接池与缓存配置的冲突:你用了默认配置的
PooledConnectionFactory,缓存级别是CACHE_CONSUMER,每个节点最多10个并发消费者。在高负载下,这种配置会导致连接池频繁创建/销毁连接,再加上故障转移的重连机制,直接把Broker的连接处理能力压垮。 - 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_CONNECTION或CACHE_SESSION,减少连接的频繁创建/销毁 - 优化连接池参数:设置
maxConnections(建议和Broker的maximumConnections匹配)、idleTimeout(比如300000毫秒),避免连接池里的连接频繁超时断开 - 限制重连频率:在客户端的故障转移URL里添加
initialReconnectDelay=1000&maxReconnectDelay=5000,避免短时间内大量重连请求冲击Broker
3. 优化Broker的连接处理配置
- 关闭异步连接关闭:在Broker的TCP连接URL里添加
transport.closeAsync=false(默认是异步关闭,容易导致CountDownLatch等待),改为同步关闭,确保连接关闭时所有内部任务都能完成 - 提升线程池大小:修改
activemq.xml里的transportConnector的threadPoolSize参数,比如设置为200,提升连接处理的并发能力 - 优化无效连接清理:确保
AbstractInactivityMonitor的keepAliveInterval设置合理(比如30000毫秒),及时清理无效连接,减少不必要的关闭操作
4. 临时应急方案(如果暂时无法升级)
- 手动重启Broker:能快速释放被阻塞的锁和线程,但这只是临时解决,无法根治问题
- 降低客户端负载:减少每个客户端节点的并发消费者数量,或者限制客户端的连接池大小,降低Broker的连接处理压力
内容的提问来源于stack exchange,提问作者Giulio Pulina




