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

IBM Liberty迁移后启动首次发送MQ数据失败:会话已关闭

问题描述

将应用从IBM WebSphere 8.5迁移至IBM Liberty Server 24后,应用连接IBM MQ收发数据时出现异常:启动后首次向MQ发送数据失败,后续发送均正常,报错信息如下:

com.ibm.msg.client.jms.DetailedIllegalStateException: MQJCA1020: The session is closed.
at com.ibm.mq.connector.services.JCAExceptionBuilder.buildException(JCAExceptionBuilder.java:189) ~[com.ibm.mq.connector.jar:?]
at com.ibm.mq.connector.services.JCAExceptionBuilder.buildException(JCAExceptionBuilder.java:111) ~[com.ibm.mq.connector.jar:?]
at com.ibm.mq.connector.outbound.SessionWrapper.assertOpen(SessionWrapper.java:939) ~[com.ibm.mq.connector.jar:?]
at com.ibm.mq.connector.outbound.SessionWrapper.createObjectMessage(SessionWrapper.java:210) ~[com.ibm.mq.connector.jar:?]

已确认MQ连接无异常,当前Liberty的server.xml配置如下:

<featureManager>
    <!--The following features are available in all editions of Liberty.-->
    <feature>appSecurity-2.0</feature>
    <feature>ejbLite-3.2</feature>
    <feature>jdbc-4.0</feature>
    <feature>jsp-2.3</feature>
    <feature>servlet-3.1</feature>
    <feature>wmqJmsClient-2.0</feature>
    <feature>jmsMdb-3.2</feature>
</featureManager>
<applicationManager autoExpand="true"/>
<httpEndpoint host="*" httpPort="-1" httpsPort="${httpsPort}" id="defaultHttpEndpoint"/>
<httpSession cookieName="${cookiename}" cookiePath="${cookiepath}" securityIntegrationEnabled="false"
             cookieHttpOnly="${cookiehttpOnly}" cookiesEnabled="${cookiesenabled}" cookieSecure="true"/>
<enterpriseApplication id="" location="/location/EAR.ear"
                       name="EAR">
    <web-ext context-root="" id="EAR.ear_web-ext_" moduleName="app"/>
    
</enterpriseApplication>
<library id="mssqllib">
    <fileset dir="${JDBC_DRIVER_PATH}" includes="${JDBC_DRIVER_FNAME}"/>
</library>
<dataSource beginTranForResultSetScrollingAPIs="false" beginTranForVendorAPIs="false" id="MssqlDS"
            jndiName="${JndiName}" type="javax.sql.ConnectionPoolDataSource">
    <jdbcDriver libraryRef="mssqllib"/>
    <properties databaseName="${DbName}" portNumber="${DbPort}" serverName="${DbHost}"
                useNTLMv2="true" user="${DbUser}"
                password="${DbPasswd}"/>
    <connectionManager connectionTimeout="180" maxPoolSize="10"/>
</dataSource>
<transaction heuristicRetryWait="0" propogatedOrBMTTranLifetimeTimeout="300"/>
<jmsActivationSpec id="jms/MQActSpec" maxSequentialFailureCount="10">
    <properties.mqJmsRa brokerCCDurSubQueue="SYSTEM.JMS.D.CC.SUBSCRIBER.QUEUE"
                        brokerCCSubQueue="SYSTEM.JMS.ND.CC.SUBSCRIBER.QUEUE"
                        brokerControlQueue="SYSTEM.BROKER.CONTROL.QUEUE"
                        brokerSubQueue="SYSTEM.JMS.ND.SUBSCRIBER.QUEUE" brokerVersion="1"
                        channel="${MQCHNL}" cleanupInterval="3600000"
                        destination-ref="jms/MQQ" destination="jms/MQQ"
                        hostName="${MQHOST}"
                        maxPoolDepth="20" messageRetention="YES" poolTimeout="300000"
                        port="${MQPORT}" sparseSubscriptions="FALSE"
                        maxSequentialFailureCount="10"
                        subscriptionDurability="Nondurable" subscriptionStore="MIGRATE" useJNDI="true"/>
</jmsActivationSpec>
<jmsQueueConnectionFactory id="jms/MQQCF"
                           jndiName="jms/MQQCF">
    <properties.mqJmsRa
            channel="${MQCHNL}"
            hostName="${MQHOST}"
            port="${MQPORT}"
            temporaryModel="SYSTEM.DEFAULT.MODEL.QUEUE"/>
    <connectionManager connectionTimeout="180" maxPoolSize="20" minPoolSize="1"/>
</jmsQueueConnectionFactory>
<jmsQueue id="jms/MQQ" jndiName="jms/MQQ">
    <properties.mqJmsRa baseQueueName="${MQQ}"
                        receiveCCSID="1208" receiveConversion="QMGR"/>
</jmsQueue>
<ssl id="defaultSSLConfig" keyStoreRef="defaultKeyStore" trustStoreRef="defaultTrustStore"
     clientAuthenticationSupported="true" clientKeyAlias="${clientalias}" sslProtocol="${sslProtocol}"/>
<keyStore id="defaultKeyStore" location="/location/sslconf.jks" type="JKS"
          password="${jkspassword}"/>
<keyStore id="defaultTrustStore" location="/location/sslconf.jks"/>
    <resourceAdapter id="mqJmsRa" location="${MQlibpath}/wmq.jmsra.rar">
        <classloader apiTypeVisibility="spec, ibm-api, api, third-party"/>
    </resourceAdapter>
    <variable name="wmqJmsClient.rar.location" value="${MQlibpath}/wmq.jmsra.rar"/>
</server>
解决方案

针对首次发送失败的MQJCA1020: The session is closed错误,可尝试以下调整:

  • 调整连接池初始化策略:当前jmsQueueConnectionFactory的connectionManager配置minPoolSize="1",Liberty启动时会初始化1个连接,但对应的Session可能未正确激活。添加initialPoolSize="1",确保启动时连接和Session都完成初始化:

    <connectionManager connectionTimeout="180" maxPoolSize="20" minPoolSize="1" initialPoolSize="1"/>
    
  • 禁用连接池超时回收:首次请求前,若连接池中的空闲连接被提前回收,会导致Session关闭。可调整poolTimeout参数,延长空闲连接存活时间,或设置为0禁用超时:

    <!-- 在resourceAdapter的properties.mqJmsRa中添加 -->
    <properties.mqJmsRa poolTimeout="0"/>
    
  • 检查应用端Session复用逻辑:确认应用是否在启动时提前获取了Session但未保持活跃状态,导致Liberty连接池回收该Session。建议修改应用逻辑,在发送消息前才获取Session,或添加Session有效性检查,若已关闭则重新获取。

  • 升级WMQ JMS RA版本:当前使用的wmq.jmsra.rar版本可能与Liberty 24存在兼容性问题,尝试使用与Liberty 24匹配的最新IBM MQ Resource Adapter版本,确保JCA层的Session管理逻辑适配新环境。

  • 调整事务配置:检查transaction配置中的propogatedOrBMTTranLifetimeTimeout,若首次发送涉及事务,超时时间过短可能导致Session提前关闭。可适当延长该值,或确认应用是否正确处理了事务边界。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 03:29:52