Skip to content
Advertisement

Customize the automatic reconnection settings to IBM MQ

I have written a code to connect to IBM MQ, and i am using ConnectionNameList which automatically reconnects to ibm mq.

I want to customize the reconnection which is happening implicitly. I have referred many articles on the internet but i am not able to figure it out.

This is my Queue Manager Config:

@Configuration
public class QM1Config{
    

    public String queueManager;
    public String queue;
    public String channel;
    public String connName;
    public String user;
    public String password;
    private static final int RECONNECT_TIMEOUT = 10;
    
    @Autowired
    MQService config;
    

@Bean
public MQConnectionFactory mqQueueConnectionFactory() {
    this.channel = config.getHosts().get(0).getChannel();
    this.user = config.getHosts().get(0).getUser();
    this.password = config.getHosts().get(0).getPassword();
    this.queueManager = config.getHosts().get(0).getQueueManager();
    this.queue = config.getHosts().get(0).getQueue();
    this.connName = config.getHosts().get(0).getConnName();
    System.out.println(channel+" "+connName+" "+queueManager+" "+user);
    MQConnectionFactory mqQueueConnectionFactory = new MQConnectionFactory();
    try {
        mqQueueConnectionFactory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
        mqQueueConnectionFactory.setBooleanProperty(WMQConstants.USER_AUTHENTICATION_MQCSP, false);
        mqQueueConnectionFactory.setCCSID(1208);
        mqQueueConnectionFactory.setChannel(channel);
        mqQueueConnectionFactory.setStringProperty(WMQConstants.USERID, user);
        mqQueueConnectionFactory.setStringProperty(WMQConstants.PASSWORD, password);
        mqQueueConnectionFactory.setQueueManager(queueManager);
        mqQueueConnectionFactory.setConnectionNameList(connName);
    } catch (Exception e) {
        e.printStackTrace();
        
        
    }
    return mqQueueConnectionFactory;
 
}


@Bean
public JmsListenerContainerFactory<?> qm1JmsListenerContainerFactory(@Qualifier("mqQueueConnectionFactory") MQConnectionFactory mqQueueConnectionFactory, DefaultJmsListenerContainerFactoryConfigurer configurer) throws InterruptedException {
  DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
  this.queue = config.getHosts().get(0).getQueue();
  configurer.configure(factory, mqQueueConnectionFactory);
  return factory;
}

@Bean("jmsTemplate1")
public JmsTemplate jmsTemplate(@Qualifier("mqQueueConnectionFactory") MQConnectionFactory mqQueueConnectionFactory) {
    JmsTemplate jmsTemplate1  = new JmsTemplate(mqQueueConnectionFactory);
    return jmsTemplate1;
}


}

When i stop the queue manager, i get the following exceptions every 5 seconds:

2022-04-24 01:17:43.194  WARN 6644 --- [enerContainer-1] o.s.j.l.DefaultMessageListenerContainer  : Setup of JMS message listener invoker failed for destination 'Q5' - trying to recover. Cause: JMSWMQ2002: Failed to get a message from destination 'Q5'.; nested exception is com.ibm.mq.MQException: JMSCMQ0001: IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2009' ('MQRC_CONNECTION_BROKEN').
2022-04-24 01:17:43.232 ERROR 6644 --- [enerContainer-1] o.s.j.l.DefaultMessageListenerContainer  : Could not refresh JMS Connection for destination 'Q5' - retrying using FixedBackOff{interval=5000, currentAttempts=0, maxAttempts=unlimited}. Cause: JMSWMQ0018: Failed to connect to queue manager 'QM5' with connection mode 'Client' and host name 'Client'.; nested exception is com.ibm.mq.MQException: JMSCMQ0001: IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2059' ('MQRC_Q_MGR_NOT_AVAILABLE').
2022-04-24 01:17:48.243 ERROR 6644 --- [enerContainer-1] o.s.j.l.DefaultMessageListenerContainer  : Could not refresh JMS Connection for destination 'Q5' - retrying using FixedBackOff{interval=5000, currentAttempts=1, maxAttempts=unlimited}. Cause: JMSWMQ0018: Failed to connect to queue manager 'QM5' with connection mode 'Client' and host name 'Client'.; nested exception is com.ibm.mq.MQException: JMSCMQ0001: IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2538' ('MQRC_HOST_NOT_AVAILABLE').
2022-04-24 01:17:53.245 ERROR 6644 --- [enerContainer-1] o.s.j.l.DefaultMessageListenerContainer  : Could not refresh JMS Connection for destination 'Q5' - retrying using FixedBackOff{interval=5000, currentAttempts=2, maxAttempts=unlimited}. Cause: JMSWMQ0018: Failed to connect to queue manager 'QM5' with connection mode 'Client' and host name 'Client'.; nested exception is com.ibm.mq.MQException: JMSCMQ0001: IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2538' ('MQRC_HOST_NOT_AVAILABLE').
2022-04-24 01:17:58.250 ERROR 6644 --- [enerContainer-1] o.s.j.l.DefaultMessageListenerContainer  : Could not refresh JMS Connection for destination 'Q5' - retrying using FixedBackOff{interval=5000, currentAttempts=3, maxAttempts=unlimited}. Cause: JMSWMQ0018: Failed to connect to queue manager 'QM5' with connection mode 'Client' and host name 'Client'.; nested exception is com.ibm.mq.MQException: JMSCMQ0001: IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2538' ('MQRC_HOST_NOT_AVAILABLE').

So i want that first 3 reconnection attempts should be a warn messages instead of error message as shown in above logs and 4th attempt onwards i want it to be an error message. and reconnection attempt to be every 10/15 seconds.

How do i configure these re-connection settings ?

Any help would be greatly appreciated ! Thanks !

EDIT: I have added an exception listener as follows:

public class MQExceptionListener implements ExceptionListener {
    private static final Logger LOGGER = LoggerFactory.getLogger(MQExceptionListener.class);

    int count = -1;
    

    @Override
    public void onException(JMSException ex) {
        
        if(count > 2) {
            System.out.println("COUNT - "+ count);
            count++;
                     LOGGER.error("***********************************************");
                        LOGGER.error(ex.toString()+" THIS IS EX TO STRING");
                        if (ex.getLinkedException() != null) {
                            LOGGER.error(ex.getLinkedException().toString()+" THIS IS getLinkedException TO STRING");
                        }
                        LOGGER.error("================================================");

        }else {
            System.out.println("COUNT - "+ count);
            count++;
                     LOGGER.warn("***********************************************");
                        LOGGER.warn(ex.toString()+" THIS IS EX TO STRING");
                        if (ex.getLinkedException() != null) {
                            LOGGER.warn(ex.getLinkedException().toString()+" THIS IS getLinkedException TO STRING");
                        }
                        LOGGER.warn("================================================");
                    
        }
            
    }
}

Now My logs are as follows:

COUNT - 1
2022-04-24 14:41:04.905  WARN 9268 --- [enerContainer-1] com.mq.sslMQ.MQExceptionListener         : ***********************************************
2022-04-24 14:41:04.905  WARN 9268 --- [enerContainer-1] com.mq.sslMQ.MQExceptionListener         : com.ibm.msg.client.jms.DetailedIllegalStateException: JMSWMQ0018: Failed to connect to queue manager 'QM5' with connection mode 'Client' and host name 'Client'.
Check 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. THIS IS EX TO STRING
2022-04-24 14:41:04.905  WARN 9268 --- [enerContainer-1] com.mq.sslMQ.MQExceptionListener         : com.ibm.mq.MQException: JMSCMQ0001: IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2538' ('MQRC_HOST_NOT_AVAILABLE'). THIS IS getLinkedException TO STRING
2022-04-24 14:41:04.905  WARN 9268 --- [enerContainer-1] com.mq.sslMQ.MQExceptionListener         : ================================================
2022-04-24 14:41:04.905 ERROR 9268 --- [enerContainer-1] o.s.j.l.DefaultMessageListenerContainer  : Could not refresh JMS Connection for destination 'Q5' - retrying using FixedBackOff{interval=5000, currentAttempts=1, maxAttempts=unlimited}. Cause: JMSWMQ0018: Failed to connect to queue manager 'QM5' with connection mode 'Client' and host name 'Client'.; nested exception is com.ibm.mq.MQException: JMSCMQ0001: IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2538' ('MQRC_HOST_NOT_AVAILABLE').

I dont want the default message listener container log to be printed onto console. how do we achieve that ?

Advertisement

Answer

I would add that the 5 second interval reconnect attempts are the DefaultMessageListenerContainer trying to reconnect. The default reconnect interval is 5 seconds – DEFAULT_RECOVERY_INTERVAL, so I’m not thinking that this involves the MQ reconnect mechanism.

With the exception handler listed above in place, you could programatically change the DefaultMessageListenerContainer setRecoveryInterval() or use setBackOff() to control the backoff interval.

As to disabling the logging, setting the log level for the DefaultMessageListenerContainer to FATAL should do it.

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement