如何使过期的 IBM MQ 连接保持活动状态,而不是断开连接



我们有一个基本的适配器=>通道=>带有int-jms:message-driven-channel-adapterint-jms:outbound-channel-adapter的适配器模式。连接工厂是一个com.ibm.mq.jms.MQConnectionFactory(下面的代码)。它从 MQSeries 代理 (9+) 获取发送到另一个 MQSeries 代理 (6+) 的消息。

此桥适用于我们的大多数收件人,但其中一个遇到了问题。当网桥在一段时间内不处于活动状态时,连接将变为"无效",一旦新消息到达,网桥将无法发送它。据我介绍,connectionFactory 的默认行为是在检测到出站已断开连接后立即重新连接。在这里,它没有检测到"断开连接",而是尝试使用以前的连接并失败:

Caused by: javax.jms.JMSException: MQJMS2007: failed to send message to MQ queue....  
Caused by: com.ibm.mq.MQException: MQJE001: Completion Code '2', Reason '2009'.

我不擅长网络/套接字(等等),但听起来接收方的东西已经过期(没有断开连接通知)。听起来连接上的"keepalive"选项在这里会有所帮助,但我无法在 Spring Integration JMS 和/或 IBM MQ 类中找到这样的机制。

有没有人知道我如何从弹簧集成方面执行这样的保持活动?或者关于为什么此连接过期而不通知的想法?

<beans>
<int:channel id="channelMQ_MQ" ></int:channel>
<!-- Source : MQseries -->
<!-- ... --> 

<!-- Destination MQ_SERIES      -->
<!- ... -->
<bean id="jmsQueueOut" class="com.ibm.mq.jms.MQQueue" depends-on="jmsConnectionFactory">
...
</bean>

<bean id="jmsConnectionFactory2" class="com.ibm.mq.jms.MQConnectionFactory">
<property name="queueManager" value="..." />
<property name="connectionNameList" value="..." />
<property name="channel" value="..." />
<property name="transportType" value="1" />
</bean>

<bean id="jmsConnectionFactory_cred2"
class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter">
<property name="targetConnectionFactory" ref="jmsConnectionFactory2" />
<property name="username" value="..."/> 
<property name="password" value="..."/> 
</bean> 
<bean id="connectionFactoryCaching2"
class="org.springframework.jms.connection.CachingConnectionFactory">
<property name="targetConnectionFactory" ref="jmsConnectionFactory_cred2" />
<property name="sessionCacheSize" value="..." />
</bean>

<int-jms:outbound-channel-adapter channel="channelMQ_MQ" 
id="jmsOut" 
destination="jmsQueueOut" 
connection-factory="connectionFactoryCaching2" 
delivery-persistent="true" 
explicit-qos-enabled="true" 
session-transacted="true" >
</int-jms:outbound-channel-adapter>
</beans>

编辑 1

  • MQSeries 版本 6
  • IBM Mq 类 : 9.1.5
  • 弹簧集成 : 5.5.13
  • MQSeries 设置 :
    • HBINT : 60
    • 凯恩特 : 120
    • SHARECNV => 在版本 6 上不存在

我们花了一点时间才找到这个技巧,但我们最终找到了合适的解决方案......

您需要在系统和应用程序端进行设置:

(在docker-compose中,需要使用 "systctls 子句")

系统:

- net.ipv4.tcp_keepalive_intvl=30
- net.ipv4.tcp_keepalive_probes=2
- net.ipv4.tcp_keepalive_time=60

应用

System.setProperty("com.ibm.mq.cfg.TCP.KeepAlive","YES");

(有多种方法可以设置此系统变量。这只是其中之一,例如)

最新更新