You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot JavaFX应用休眠后IBM MQ JMS重连失败求助

问题描述

我开发了一个Spring Boot JavaFX胖客户端应用,通过Spring Boot JMS(JmsTemplate,由Spring Boot自动配置)连接IBM MQ。已在application.properties中配置如下:

ibm.mq.queueManager = queuemanager
ibm.mq.channel = channel I am using
ibm.mq.connName = server to connect to
ibm.mq.user = user name
ibm.mq.password= the password
ibm.mq.queue = the queue to use
ibm.mq.reconnect=QMGR

应用启动时的跟踪日志如下:

2024-01-25 11:48:17:151 TRACE c.i.m.s.b.MQConfigurationProperties - constructor
2024-01-25 11:48:17:161 TRACE c.i.m.s.b.MQConnectionFactoryConfiguration - Creating caching MQConnectionFactory
2024-01-25 11:48:17:163 TRACE c.i.m.s.b.MQConnectionFactoryFactory - constructor
2024-01-25 11:48:17:163 TRACE c.i.m.s.b.MQConnectionFactoryFactory - createConnectionFactory for class MQConnectionFactory
2024-01-25 11:48:17:163 TRACE c.i.m.s.b.MQConfigurationSslBundles - SSLBundles are not supported
2024-01-25 11:48:17:163 TRACE c.i.m.s.b.MQConnectionFactoryFactory - configuring TLS Store system properties
2024-01-25 11:48:17:163 TRACE c.i.m.s.b.MQConnectionFactoryFactory - createConnectionFactoryInstance for class MQConnectionFactory
2024-01-25 11:48:17:342 TRACE c.i.m.s.b.MQConnectionFactoryFactory - configureConnectionFactory
2024-01-25 11:48:17:342 TRACE c.i.m.s.b.MQConfigurationProperties - queueManager    : XX_XXX_X
2024-01-25 11:48:17:342 TRACE c.i.m.s.b.MQConfigurationProperties - applicationName : null
2024-01-25 11:48:17:342 TRACE c.i.m.s.b.MQConfigurationProperties - ccdtUrl         : null
2024-01-25 11:48:17:342 TRACE c.i.m.s.b.MQConfigurationProperties - channel         : THE_CHANNEL
2024-01-25 11:48:17:342 TRACE c.i.m.s.b.MQConfigurationProperties - clientId        : null
2024-01-25 11:48:17:342 TRACE c.i.m.s.b.MQConfigurationProperties - connName        : THE_MQ_SERVER
2024-01-25 11:48:17:342 TRACE c.i.m.s.b.MQConfigurationProperties - reconnectOption : 'QMGR' [0x04000000]
2024-01-25 11:48:17:342 TRACE c.i.m.s.b.MQConfigurationProperties - sslCipherSpec   : null
2024-01-25 11:48:17:342 TRACE c.i.m.s.b.MQConfigurationProperties - sslCipherSuite  : null
2024-01-25 11:48:17:342 TRACE c.i.m.s.b.MQConfigurationProperties - sslKeyresetcount: -1
2024-01-25 11:48:17:342 TRACE c.i.m.s.b.MQConfigurationProperties - sslPeerName     : null
2024-01-25 11:48:17:342 TRACE c.i.m.s.b.MQConfigurationProperties - sslBundle       : null
2024-01-25 11:48:17:342 TRACE c.i.m.s.b.MQConfigurationProperties - tempModel       : null
2024-01-25 11:48:17:343 TRACE c.i.m.s.b.MQConfigurationProperties - tempQPrefix     : null
2024-01-25 11:48:17:343 TRACE c.i.m.s.b.MQConfigurationProperties - tempTopicPrefix : null
2024-01-25 11:48:17:343 TRACE c.i.m.s.b.MQConfigurationProperties - user            : 'XXXXXX'
2024-01-25 11:48:17:343 TRACE c.i.m.s.b.MQConfigurationProperties - password set    : YES
2024-01-25 11:48:17:343 TRACE c.i.m.s.b.MQConfigurationProperties - sslFIPSRequired        : false
2024-01-25 11:48:17:343 TRACE c.i.m.s.b.MQConfigurationProperties - useIBMCipherMappings   : true
2024-01-25 11:48:17:343 TRACE c.i.m.s.b.MQConfigurationProperties - userAuthenticationMQCSP: true
2024-01-25 11:48:17:343 TRACE c.i.m.s.b.MQConfigurationProperties - outboundSNI            : ''
2024-01-25 11:48:17:343 TRACE c.i.m.s.b.MQConfigurationProperties - channelSharing         : ''
2024-01-25 11:48:17:343 TRACE c.i.m.s.b.MQConfigurationProperties - balancingAppType       : '' [0]
2024-01-25 11:48:17:343 TRACE c.i.m.s.b.MQConfigurationProperties - balancingTimeout       : '' [-1]
2024-01-25 11:48:17:343 TRACE c.i.m.s.b.MQConfigurationProperties - balancingOptions       : '' [0]
2024-01-25 11:48:17:343 TRACE c.i.m.s.b.MQConfigurationProperties - jndiCF          : null
2024-01-25 11:48:17:343 TRACE c.i.m.s.b.MQConfigurationProperties - jndiProviderUrl : null
2024-01-25 11:48:17:343 TRACE c.i.m.s.b.MQConfigurationProperties - JKS keystore           : null
2024-01-25 11:48:17:343 TRACE c.i.m.s.b.MQConfigurationProperties - JKS keystore pw set    : NO
2024-01-25 11:48:17:343 TRACE c.i.m.s.b.MQConfigurationProperties - JKS truststore         : null
2024-01-25 11:48:17:343 TRACE c.i.m.s.b.MQConfigurationProperties - JKS truststore pw set  : NO
2024-01-25 11:48:17:343 TRACE c.i.m.s.b.MQConfigurationProperties - No additional properties defined
2024-01-25 11:48:17:343 TRACE c.i.m.s.b.MQConfigurationProperties - Pooling is disabled

应用运行状态一切正常,但部分用户在不关闭应用的情况下合上笔记本盖子(应用进入休眠状态),再次打开笔记本继续使用时,重连失败。日志中报错如下:

nested exception is com.ibm.mq.MQException: JMSCMQ0001: 
IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2556' ('MQRC_RECONNECT_TIMED_OUT').

目前只能通过重启应用恢复正常,请问我遗漏了哪些配置或有什么解决办法?


解决方案

一、补充IBM MQ重连核心配置

仅配置ibm.mq.reconnect=QMGR不足以应对休眠后网络恢复的延迟,需补充以下参数优化重连逻辑:

  • 延长重连超时时间:添加ibm.mq.reconnectTimeout=30(单位:秒),默认超时可能过短,导致网络未完全恢复时重连失败。
  • 启用无限重连尝试:添加ibm.mq.reconnectRetryCount=-1,设置为-1表示无限制重试,避免因有限次数耗尽导致重连终止。
  • 配置重连间隔:添加ibm.mq.reconnectRetryInterval=5(单位:秒),避免短时间内频繁重试浪费资源。

更新后的application.properties相关配置:

ibm.mq.reconnect=QMGR
ibm.mq.reconnectTimeout=30
ibm.mq.reconnectRetryCount=-1
ibm.mq.reconnectRetryInterval=5

二、启用并配置JMS连接池

启动日志显示Pooling is disabled,未启用连接池时,休眠后的旧连接无法被自动回收重建。建议启用连接池:

  1. 添加连接池依赖(若未添加)
<dependency>
    <groupId>org.messaginghub</groupId>
    <artifactId>pooled-jms</artifactId>
</dependency>
  1. 配置连接池参数
spring.jms.pool.enabled=true
spring.jms.pool.max-connections=10
spring.jms.pool.idle-timeout=30000
spring.jms.pool.connection-timeout=60000
  • enabled=true:开启连接池
  • idle-timeout:空闲连接30秒后自动销毁,避免持有无效连接
  • connection-timeout:获取连接超时时间设为60秒,给重连留足时间

三、监听系统唤醒事件,主动重建连接

JavaFX应用可监听系统休眠/唤醒事件,在唤醒时主动重置JMS连接:

import javafx.application.Application;
import javafx.application.Platform;
import javafx.stage.Stage;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.connection.CachingConnectionFactory;
import javax.jms.JmsException;

public class MainApp extends Application {
    private JmsTemplate jmsTemplate;
    private CachingConnectionFactory connectionFactory;

    // 假设通过Spring注入jmsTemplate和connectionFactory

    @Override
    public void start(Stage primaryStage) {
        // 注册系统唤醒监听器(依赖AWT)
        try {
            System.setProperty("java.awt.headless", "false");
            java.awt.SystemTray.getSystemTray().add(new java.awt.TrayIcon(new java.awt.ImageIcon("").getImage()) {
                @Override
                public void mouseClicked(java.awt.event.MouseEvent e) {
                    // 系统唤醒时触发连接重建
                    Platform.runLater(MainApp.this::rebuildJmsConnection);
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void rebuildJmsConnection() {
        try {
            // 重置旧连接
            connectionFactory.resetConnection();
            // 测试新连接有效性
            jmsTemplate.execute(session -> {
                session.createQueue(jmsTemplate.getDefaultDestinationName());
                return null;
            });
        } catch (JmsException e) {
            e.printStackTrace();
            // 可添加重试逻辑
        }
    }
}

四、捕获重连异常并手动重试

在消息发送/接收逻辑中,针对MQRC_RECONNECT_TIMED_OUT(2556)异常添加重试机制:

public void sendMessage(String content) {
    int maxRetries = 3;
    int currentRetry = 0;
    while (currentRetry < maxRetries) {
        try {
            jmsTemplate.convertAndSend(content);
            return;
        } catch (JmsException e) {
            if (e.getCause() instanceof com.ibm.mq.MQException) {
                com.ibm.mq.MQException mqEx = (com.ibm.mq.MQException) e.getCause();
                if (mqEx.getReason() == 2556) {
                    currentRetry++;
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                    }
                } else {
                    throw e;
                }
            } else {
                throw e;
            }
        }
    }
    throw new RuntimeException("MQ重连失败,已达最大重试次数");
}

五、检查MQ服务器端配置

确认服务器端允许重连:

  • 队列管理器的RECONNECT属性需设为ENABLED
  • 通道的SHARECNV参数避免设置过高,防止通道共享导致重连冲突
  • 服务器端未限制客户端连接超时时间或次数

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 16:34:53