1

I have used MQQueueConnectionFactory without CLIENTRECONNECTTIMEOUT and CLIENTRECONNECTOPTIONS. Using Spring JmsTemplate to send a message.

<bean id="mqCachingConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
    <property name="targetConnectionFactory" ref="mqConnectionFactory" />
    <property name="sessionCacheSize" value="20" /> 
    <property name="reconnectOnException" value="true"/>

Not using any of the following IBM MQ connection factory settings.

firstMQConnectionFactory.setClientReconnectOptions(WMQConstancs.WMQ_CLIENT_RECONNECT;
firstMQConnectionFactory.setClientReconnectTimeout(5);

I am letting spring CachingConnectionFactory detect the errors and attempt the reconnection.

The problem comes when the queue manager goes down unexpectedly. Spring CachingConnectionFactory detects this and begins a new connection. Now IBM MQ connection factory tries to create a new connection. It waits for 30 mins before giving up with MQRC_HOST_NOT_AVAILABLE. Stack trace:

org.springframework.jms.IllegalStateException: JMSWMQ0018: Failed to connect to queue manager 'QMGRID' with connection mode 'Client' and host name 'QMGRHOST(port)'.; nested exception is com.ibm.msg.client.jms.DetailedIllegalStateException: JMSWMQ0018: Failed to connect to queue manager 'QMGR' with connection mode 'Client' and host name 'hostname(62306)'.\nCheck the queue manager is started and if running in client mode, check there is a listener running. Please see the linked exception for more information.; nested exception is com.ibm.mq.MQException: JMSCMQ0001: IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2538' ('MQRC_HOST_NOT_AVAILABLE').
Caused by: com.ibm.mq.jmqi.JmqiException: CC=2;RC=2538;AMQ9213: A communications error for 'TCP' occurred. [1=java.net.ConnectException[Connection timed out (Connection timed out)],3=connnectUsingLocalAddress,4=TCP,5=Socket.connect]
java.net.ConnectException: Connection timed out (Connection timed out)
at java.net.PlainSocketImpl.socketConnect(Native Method) ~[?:1.8.0_172]
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) ~[?:1.8.0_172]
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) ~[?:1.8.0_172]
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) ~[?:1.8.0_172]
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) ~[?:1.8.0_172]
at java.net.Socket.connect(Socket.java:589) ~[?:1.8.0_172]
at java.net.Socket.connect(Socket.java:538) ~[?:1.8.0_172]
at com.ibm.mq.jmqi.remote.impl.RemoteTCPConnection$5.run(RemoteTCPConnection.java:825) ~[com.ibm.mq.jmqi-9.0.0.3.jar:9.0.0.3 - p900-003-180226]
at com.ibm.mq.jmqi.remote.impl.RemoteTCPConnection$5.run(RemoteTCPConnection.java:816) ~[com.ibm.mq.jmqi-9.0.0.3.jar:9.0.0.3 - p900-003-180226]
at java.security.AccessController.doPrivileged(Native Method) ~[?:1.8.0_172]
at com.ibm.mq.jmqi.remote.impl.RemoteTCPConnection.connnectUsingLocalAddress(RemoteTCPConnection.java:816) ~[com.ibm.mq.jmqi-9.0.0.3.jar:9.0.0.3 - p900-003-180226]
at com.ibm.mq.jmqi.remote.impl.RemoteTCPConnection.protocolConnect(RemoteTCPConnection.java:1279) ~[com.ibm.mq.jmqi-9.0.0.3.jar:9.0.0.3 - p900-003-180226]
at com.ibm.mq.jmqi.remote.impl.RemoteConnection.connect(RemoteConnection.java:1003) ~[com.ibm.mq.jmqi-9.0.0.3.jar:9.0.0.3 - p900-003-180226]
at com.ibm.mq.jmqi.remote.impl.RemoteConnectionSpecification.getSessionFromNewConnection(RemoteConnectionSpecification.java:409) ~[com.ibm.mq.jmqi-9.0.0.3.jar:9.0.0.3 - p900-003-180226]
at com.ibm.mq.jmqi.remote.impl.RemoteConnectionSpecification.getSession(RemoteConnectionSpecification.java:305) ~[com.ibm.mq.jmqi-9.0.0.3.jar:9.0.0.3 - p900-003-180226]
at com.ibm.mq.jmqi.remote.impl.RemoteConnectionPool.getSession(RemoteConnectionPool.java:155) ~[com.ibm.mq.jmqi-9.0.0.3.jar:9.0.0.3 - p900-003-180226]
at com.ibm.mq.jmqi.remote.api.RemoteFAP.jmqiConnect(RemoteFAP.java:1716) ~[com.ibm.mq.jmqi-9.0.0.3.jar:9.0.0.3 - p900-003-180226]
at com.ibm.mq.jmqi.remote.api.RemoteFAP.jmqiConnect(RemoteFAP.java:1280) ~[com.ibm.mq.jmqi-9.0.0.3.jar:9.0.0.3 - p900-003-180226]
at com.ibm.mq.ese.jmqi.InterceptedJmqiImpl.jmqiConnect(InterceptedJmqiImpl.java:377) ~[com.ibm.mq.jmqi-9.0.0.3.jar:9.0.0.3 - p900-003-180226]
at com.ibm.mq.ese.jmqi.ESEJMQI.jmqiConnect(ESEJMQI.java:562) ~[com.ibm.mq.jmqi-9.0.0.3.jar:9.0.0.3 - p900-003-180226]
at com.ibm.msg.client.wmq.internal.WMQConnection.< init>(WMQConnection.java:356) ~[com.ibm.mqjms-9.0.0.3.jar:9.0.0.3 - p900-003-180226]
at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createV7ProviderConnection(WMQConnectionFactory.java:8474) ~[com.ibm.mqjms-9.0.0.3.jar:9.0.0.3 - p900-003-180226]
at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createProviderConnection(WMQConnectionFactory.java:7814) ~[com.ibm.mqjms-9.0.0.3.jar:9.0.0.3 - p900-003-180226]
at com.ibm.msg.client.jms.admin.JmsConnectionFactoryImpl._createConnection(JmsConnectionFactoryImpl.java:299) ~[com.ibm.mqjms-9.0.0.3.jar:9.0.0.3 - p900-003-180226]
at com.ibm.msg.client.jms.admin.JmsConnectionFactoryImpl.createConnection(JmsConnectionFactoryImpl.java:236) ~[com.ibm.mqjms-9.0.0.3.jar:9.0.0.3 - p900-003-180226]
at com.ibm.mq.jms.MQConnectionFactory.createCommonConnection(MQConnectionFactory.java:6016) ~[com.ibm.mqjms-9.0.0.3.jar:9.0.0.3 - p900-003-180226]
at com.ibm.mq.jms.MQQueueConnectionFactory.createQueueConnection(MQQueueConnectionFactory.java:111) ~[com.ibm.mqjms-9.0.0.3.jar:9.0.0.3 - p900-003-180226]
at com.ibm.mq.jms.MQQueueConnectionFactory.createConnection(MQQueueConnectionFactory.java:187) ~[com.ibm.mqjms-9.0.0.3.jar:9.0.0.3 - p900-003-180226]
at org.springframework.jms.connection.SingleConnectionFactory.doCreateConnection(SingleConnectionFactory.java:403) ~[spring-jms-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.jms.connection.SingleConnectionFactory.initConnection(SingleConnectionFactory.java:343) ~[spring-jms-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.jms.connection.SingleConnectionFactory.getConnection(SingleConnectionFactory.java:321) ~[spring-jms-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.jms.connection.SingleConnectionFactory.createConnection(SingleConnectionFactory.java:236) ~[spring-jms-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.jms.support.JmsAccessor.createConnection(JmsAccessor.java:196) ~[spring-jms-5.0.6.RELEASE.jar:5.0.6.RELEASE]
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:494) ~[spring-jms-5.0.6.RELEASE.jar:5.0.6.RELEASE]
... 67 more\n}

Can we just set the following setting to limit this connection timeout?

firstMQConnectionFactory.setClientReconnectTimeout(5);

Will this option will take into effect event when CLIENTRECONNECTOPTIONS is not set and is disabled by default?

JoshMc
  • 10,239
  • 2
  • 19
  • 38
CoderPraBhu
  • 346
  • 3
  • 9
  • It doesn't try re connection after 30 mins. It gives up connecting to the mq host after 30 mins. I want to control the time it waits before giving it up. – CoderPraBhu Jul 25 '18 at 23:38
  • Yes. It's taking 30 mins for connection timed out error. Users see request spinning in the browser. Trying to time it out in 5 seconds. The MQ operation we are trying to do it is optional. Unfortunately I can't order the qmgr to be taken down. It happens only in extreme cases. Spring JMS would recovers as soon as the qmgr is up. But while it's down, trying to minimize user impact. They will see slowness for 5 seconds but at least won't be blocked. Updated question with stack trace for timeout that shows where it was waiting. Need to know if any class in this trace uses the timeout config. – CoderPraBhu Jul 26 '18 at 01:11
  • Do you get the same result if you point your config to a IP on your network that is not assigned to any server? – JoshMc Jul 26 '18 at 03:08
  • I was able to reproduce same error using a random IP address. Was able to control the timeout using System.setProperty('com.ibm.mq.cfg.TCP.Connect_Timeout', '5'). Thank you. – CoderPraBhu Jul 27 '18 at 00:21
  • Glad this worked for you. I have added a answer with these details. Please accept it by selecting the "check mark" to the left of the answer. Thank you. – JoshMc Jul 27 '18 at 00:37
  • I know this is an old post, but I have the same issue. It's strange that the solution is to change a global property. What if I want some connections to have 30 mins and others to have 5 secs timeout? – Aladin Apr 23 '20 at 09:30
  • 1
    @Aladin I don't think you have that option in a thread safe manner. If you want to have SO alert anyone other than the original poster you need to @ tag them like I did for you. – JoshMc Sep 21 '20 at 17:39

1 Answers1

4

Based on the description of the issue it appears java is taking 30 minutes to timeout on the initial connection.

MQ has a parameter to allow you to tune the TCP connect timeout.

From what I can tell if you do not set the parameter it depends on the java implementation and the underlying OS settings on how long it will take to timeout, in your case this must be 30 minutes, but this does seem very high, on Linux for instance I believe the default is 93 seconds.

There are two ways to accomplish this:

  1. By setting the java system property com.ibm.mq.cfg.TCP.Connect_Timeout to the number of seconds you want for the connection to timeout. This can be done in two ways:
    • Programmatically using System.setProperty('com.ibm.mq.cfg.TCP.Connect_Timeout', '5')
    • On the command line by passing -Dcom.ibm.mq.cfg.TCP.Connect_Timeout=5
  2. You can also put Connect_Timeout=5 in the TCP: stanza of a mqclient.ini file and IBM MQ Classes for JMS will pick this up from the various default locations. Look at my answer to "Where should MQClient.ini reside for an IIS Application?" for information on where MQ will look for this file. Note the answer was written with Windows OS in mind, but the link to the IBM Knowledge Center documentation will show you the Unix/Linux paths as well.

    TCP:
       Connect_Timeout=5
    
JoshMc
  • 10,239
  • 2
  • 19
  • 38