Oracle SOA对接ActiveMQ偶发JMS连接失败EOFException问题问询
ActiveMQ JMS连接偶发EOFException排查方案
该低频率偶发报错是ActiveMQ生产端接入的典型问题,错误日志核心信息如下:
JMSMessageProducer_A JMSException was caught: org.apache.activemq.ConnectionFailedException: The JMS connection has failed: java.io.EOFException The JMS connection has failed: java.io.EOFException. closeCCIConnection: [default destination = location-inbound] Destroying Application Connection Handle and invalidating pool...
根因排查优先级(从高到低)
- 网络中间设备静默断连
90%以上的低频率偶发EOF错误都是这个原因:ActiveMQ默认开启30秒间隔的TCP心跳保活,如果Broker和Oracle SOA服务器之间串了防火墙、负载均衡这类设备,且设备配置的TCP空闲会话超时时间小于心跳间隔,设备会直接静默丢弃空闲连接,不向两端发送RST断开标记,等客户端下次复用这个连接往Topic发消息时,就会触发EOF异常。排查时可以在报错对应时间点查网络设备的会话丢弃日志,同时核对两端到设备的超时参数是否匹配。 - JMS连接池未做借出校验
Oracle SOA的JMS适配器默认使用连接池缓存JMS连接,如果没有开启连接借出时的有效性校验,池子里会留存已经被断开的僵死连接,业务线程拿到僵死连接发送消息时就会抛出连接失败错误。这类错误的典型特征是报错间隔不固定,报错后连接池销毁失效连接,后续一段时间业务完全正常。 - Broker侧主动断连
查ActiveMQ服务端的activemq.log对应时间点的记录,三类Broker侧操作会触发客户端EOF报错:- Broker内存使用率触达
memoryLimit阈值,触发流控主动断开慢连接客户端 - Broker发生长时间Full GC停顿,超过心跳超时时间后断开所有客户端连接
- ActiveMQ主从架构发生主节点切换,旧主节点主动断开所有客户端连接
- Broker内存使用率触达
- 客户端侧长GC停顿
查Oracle SOA托管服务器的GC日志,如果报错时间点存在超过10秒的Full GC停顿,JVM停顿期间无法响应ActiveMQ的心跳包,Broker会判定客户端失活主动断开连接,JVM恢复后复用旧连接发消息就会报错。
修复建议
- 优先调整JMS适配器连接池配置:开启
testOnBorrow参数,连接借出前先做轻量有效性校验,直接过滤池中的僵死连接,这个配置对性能影响极小,上线后基本可以完全消除这类偶发报错对业务的影响;同时将连接的最大空闲存活时间调整为120秒,避免连接长时间闲置。 - 统一全链路超时参数:将ActiveMQ客户端、Broker端的
wireFormat.maxInactivityDuration参数统一设置为60000ms(60秒),中间网络设备的TCP空闲会话超时设置为90秒以上,保证心跳包能在会话被丢弃前正常发送,维持连接活性。 - 配置客户端自动重连:Oracle SOA配置JMS适配器连接串时,使用failover语法,配置
maxReconnectAttempts=-1、initialReconnectDelay=1000参数,遇到Broker切换、网络闪断场景时客户端会自动重试重连,不需要人工干预。 - 如果使用的是5.15.10之前的ActiveMQ 5.x版本,建议升级到5.15.x的最新稳定小版本,旧版本存在心跳线程意外终止、空闲连接异常断开的已知bug,也会触发低频率EOF报错。
内容的提问来源于stack exchange,提问作者Ganesh Gaikwad
相关产品推荐
相关产品推荐

