Обнаружение повторного подключения в клиентском приложении IBM MQ, которое использует автоматическое повторное подключение - PullRequest
2 голосов
/ 28 января 2020

Я использую IBM MQ Classes для JMS (IBM MQ Version 8.0.0.4) с настроенным автоматическим переподключением. Согласно документам, переподключение происходит неявно. Я хотел бы выдать простую запись журнала в случае переподключения. По этой причине мне нужно как-то получить информацию, когда это произойдет.

В документации IBM на стр. Восстановление приложений Я наткнулся на раздел «Обнаружение аварийного переключения», где говорится:

Переподключение известно: Зарегистрируйте обработчик событий MQCBT_EVENT_HANDLER в администраторе очередей. Обработчик события публикуется с MQRC_RECONNECTING, когда клиент начинает пытаться переподключиться к серверу, и MQRC_RECONNECTED после успешного переподключения. Затем вы можете запустить подпрограмму, чтобы восстановить sh предсказуемое состояние, чтобы клиентское приложение могло продолжить обработку.

К сожалению, я не нашел пример кода для Java / JMS, который демонстрирует, как и где зарегистрировать такой обработчик событий. Я не знаю, поддерживается ли это даже в моем случае. Может ли кто-нибудь дать мне правильное направление или даже предоставить пример кода? Большое спасибо.

Обновление вопроса от 5 февраля 2020 года:

Добавлен следующий пример кода, созданный мной, после получения первоначального ответа Саши от 27 января, 2020.

public static void main(String[] args) {
    Connection connection = null;
    Session session = null;
    Object destination = null;
    MessageProducer producer = null;

    try {
        JmsFactoryFactory jmsFactoryFactory = JmsFactoryFactory.getInstance(WMQConstants.WMQ_PROVIDER);
        JmsConnectionFactory cf = jmsFactoryFactory.createConnectionFactory();

        cf.setStringProperty(WMQConstants.WMQ_HOST_NAME, HOST);
        cf.setIntProperty(WMQConstants.WMQ_PORT, PORT);
        cf.setStringProperty(WMQConstants.WMQ_CHANNEL, CHANNEL);
        cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT);
        cf.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER, QM_NAME);
        cf.setIntProperty(WMQConstants.WMQ_CLIENT_RECONNECT_OPTIONS, WMQConstants.WMQ_CLIENT_RECONNECT);
        cf.setIntProperty(WMQConstants.WMQ_CLIENT_RECONNECT_TIMEOUT, RECONNECT_TIMEOUT);

        connection = cf.createConnection();
        connection.setExceptionListener(new MQExceptionListener());
        session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        destination = session.createQueue(QUEUE);
        producer = session.createProducer((Destination)destination);
        connection.start();
    } catch (JMSException ex) {
        LOGGER.error(ex.toString());
    }
}

public class MQExceptionListener implements ExceptionListener {
    public void onException(JMSException e) {
        System.out.println(e);
        if(e.getLinkedException() != null)
            System.out.println(e.getLinkedException());
    }
}

Вот что я получаю в журналах:

ERROR [Main.main:57] (main) com.ibm.msg.client.jms.DetailedIllegalStateException: JMSWMQ0018: Failed to connect to queue manager '<hostname>' with connection mode 'Client' and host name '<hostname>(<port>)'.
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.
ERROR [Main.main:61] (main) Inner exceptions:
ERROR [Main.main:65] (main) com.ibm.mq.MQException: JMSCMQ0001: IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2538' ('MQRC_HOST_NOT_AVAILABLE').
ERROR [Main.main:65] (main) com.ibm.mq.jmqi.JmqiException: CC=2;RC=2538;AMQ9204: Connection to host '<hostname>(<port>)' rejected. [1=com.ibm.mq.jmqi.JmqiException[CC=2;RC=2538;AMQ9204: Connection to host '<hostname>/<ip>:<port>' rejected. [1=java.net.ConnectException[Connection refused: connect],3=<hostname>/<ip>:<port>,4=TCP,5=Socket.connect]],3=<hostname>(<port>),5=RemoteTCPConnection.bindAndConnectSocket]
ERROR [Main.main:65] (main) com.ibm.mq.jmqi.JmqiException: CC=2;RC=2538;AMQ9204: Connection to host '<hostname>/<ip>:<port>' rejected. [1=java.net.ConnectException[Connection refused: connect],3=<hostname>/<ip>:<port>,4=TCP,5=Socket.connect]
ERROR [Main.main:65] (main) java.net.ConnectException: Connection refused: connect

Обновление вопроса от 11 февраля 2020 года:

I Я добавил эти дополнения на основе отзывов, полученных Sashi 5 февраля 2020 года.

Я попытался создать минимальное приложение, которое подключается к экземпляру IBM MQ. Вот код:

Приложение. java

public class Application {
    private static final Logger LOGGER = LoggerFactory.getLogger(Application.class);

    public static void main(String[] args) {
        new Application().run();
    }

    private void run() {
        MQWriter writer = new MQWriter();
        int i = 1;
        while (true) {
            String message = "Hello Testing " + i;
            LOGGER.info("Sending message {} to MQ server...", message);
            writer.write(message);
            i++;
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

MQConnectionDetails. java

public class MQConnectionDetails {
    public static final String HOST = "XXX.XXX.XXX.XXX";
    public static final int PORT = 1414;
    public static final String QM_NAME = "QM1";
    public static final String CHANNEL = "DEV.APP.SVRCONN";
    public static final String QUEUE = "DEV.QUEUE.1";
    public static final int RECONNECT_TIMEOUT = 60; // 1 minute
}

MQWriter. java

public class MQWriter {

    private static final Logger LOGGER = LoggerFactory.getLogger(MQWriter.class);

    private Connection connection = null;
    private Session session = null;
    private Object destination = null;
    private MessageProducer producer = null;

    public MQWriter() {
        try {
            JmsFactoryFactory jff = JmsFactoryFactory.getInstance(WMQConstants.WMQ_PROVIDER);
            JmsConnectionFactory jcf = jff.createConnectionFactory();
            jcf.setStringProperty(WMQConstants.WMQ_HOST_NAME, MQConnectionDetails.HOST);
            jcf.setIntProperty(WMQConstants.WMQ_PORT, MQConnectionDetails.PORT);
            jcf.setStringProperty(WMQConstants.WMQ_CHANNEL, MQConnectionDetails.CHANNEL);
            jcf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT);
            jcf.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER, MQConnectionDetails.QM_NAME);
            jcf.setIntProperty(WMQConstants.WMQ_CLIENT_RECONNECT_OPTIONS, WMQConstants.WMQ_CLIENT_RECONNECT);
            jcf.setIntProperty(WMQConstants.WMQ_CLIENT_RECONNECT_TIMEOUT, MQConnectionDetails.RECONNECT_TIMEOUT);

            LOGGER.info("Initializing connection to write queue {} on {}:{}...",
                    MQConnectionDetails.QUEUE,
                    MQConnectionDetails.HOST,
                    MQConnectionDetails.PORT);
            connection = jcf.createConnection();
            connection.setExceptionListener(new MQExceptionListener());
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            destination = session.createQueue(MQConnectionDetails.QUEUE);
            producer = session.createProducer((Destination)destination);
            connection.start();
        } catch (JMSException ex) {
            LOGGER.error("Error initializing connection to write queue", ex);
        }
    }

    public void write(String message) {
        try {
            TextMessage textMessage = session.createTextMessage(message);
            producer.send(textMessage);
        } catch (Exception ex) {
            LOGGER.error("Error sending message to write queue", ex);
        }
    }
}

MQExceptionListener. java

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

    public void onException(JMSException ex) {
        LOGGER.error("=====");
        LOGGER.error(ex.toString());
        if (ex.getLinkedException() != null) {
            LOGGER.error(ex.getLinkedException().toString());
        }
        LOGGER.error("=====");
    }
}

Тестовый сценарий, который я запустил, выглядит следующим образом:

  1. Убедитесь, что IBM MQ доступен через TCP-порт 1414 (контейнер IBM MQ Docker, работающий на Amazon EC2).
  2. Запустите указанное выше приложение (Приложение. java) и убедитесь, что он отправляет сообщения в очередь.
  3. Измените конфигурацию брандмауэра в группах безопасности Amazon EC2, изменив порт с 1414 на 1415, что делает IBM MQ недоступным для клиента.

This Вот что я наблюдал:

  • Только после 90 секунд бездействия клиент начал выдавать исключения. Я не понимаю, потому что мой RECONNECT_TIMEOUT был установлен на 60 секунд, поэтому 30 секунд здесь.
  • MQExceptionListener вызывается только один раз (в первый раз).
  • Нет кодов причины 2544 (MQRC_RECONNECTING), присутствует только 2009 (MQRC_CONNECTION_BROKEN). Почему это так?

Вот сводка исключений, которые были выброшены:

Исключения на консоли:

2020-02-11 09:50:16,155 INFO [Application.run:21] (main) Sending message Hello Testing 13 to MQ server...
2020-02-11 09:50:17,285 INFO [Application.run:21] (main) Sending message Hello Testing 14 to MQ server...
2020-02-11 09:50:18,413 INFO [Application.run:21] (main) Sending message Hello Testing 15 to MQ server...
2020-02-11 09:50:19,555 INFO [Application.run:21] (main) Sending message Hello Testing 16 to MQ server...
2020-02-11 09:51:45,966 ERROR [MQExceptionListener.onException:14] (JMSCCThreadPoolWorker-6) =====
2020-02-11 09:51:45,966 ERROR [MQExceptionListener.onException:15] (JMSCCThreadPoolWorker-6) com.ibm.msg.client.jms.DetailedJMSException: JMSWMQ1107: A problem with this connection has occurred.
An error has occurred with the IBM MQ JMS connection.
Use the linked exception to determine the cause of this error.
2020-02-11 09:51:45,966 ERROR [MQExceptionListener.onException:17] (JMSCCThreadPoolWorker-6) com.ibm.mq.MQException: MQ delivered an asynchronous event with completion code '2', and reason '2009'.
2020-02-11 09:51:45,966 ERROR [MQExceptionListener.onException:19] (JMSCCThreadPoolWorker-6) =====
2020-02-11 09:51:45,967 ERROR [MQWriter.write:52] (main) Error sending message to write queue
com.ibm.msg.client.jms.DetailedJMSException: JMSWMQ2007: Failed to send a message to destination 'DEV.QUEUE.1'.
JMS attempted to perform an MQPUT or MQPUT1; however IBM MQ reported an error.
Use the linked exception to determine the cause of this error.
    at com.ibm.msg.client.wmq.common.internal.Reason.reasonToException(Reason.java:595)
    at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:215)
    at com.ibm.msg.client.wmq.internal.WMQMessageProducer.checkJmqiCallSuccess(WMQMessageProducer.java:1288)
    at com.ibm.msg.client.wmq.internal.WMQMessageProducer.checkJmqiCallSuccess(WMQMessageProducer.java:1245)
    at com.ibm.msg.client.wmq.internal.WMQMessageProducer.access$800(WMQMessageProducer.java:76)
    at com.ibm.msg.client.wmq.internal.WMQMessageProducer$SpiIdentifiedProducerShadow.sendInternal(WMQMessageProducer.java:906)
    at com.ibm.msg.client.wmq.internal.WMQMessageProducer$ProducerShadow.send(WMQMessageProducer.java:566)
    at com.ibm.msg.client.wmq.internal.WMQMessageProducer.send(WMQMessageProducer.java:1428)
    at com.ibm.msg.client.jms.internal.JmsMessageProducerImpl.sendMessage(JmsMessageProducerImpl.java:855)
    at com.ibm.msg.client.jms.internal.JmsMessageProducerImpl.synchronousSendInternal(JmsMessageProducerImpl.java:2055)
    at com.ibm.msg.client.jms.internal.JmsMessageProducerImpl.sendInternal(JmsMessageProducerImpl.java:1993)
    at com.ibm.msg.client.jms.internal.JmsMessageProducerImpl.send(JmsMessageProducerImpl.java:1486)
    at com.ibm.mq.jms.MQMessageProducer.send(MQMessageProducer.java:293)
    at org.example.MQWriter.write(MQWriter.java:50)
    at org.example.Application.run(Application.java:22)
    at org.example.Application.main(Application.java:13)
Caused by: com.ibm.mq.MQException: JMSCMQ0001: IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2009' ('MQRC_CONNECTION_BROKEN').
    at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:203)
    ... 14 more
Caused by: com.ibm.mq.jmqi.JmqiException: CC=2;RC=2009
    at com.ibm.mq.jmqi.remote.api.RemoteHconn$ReconnectionState.recordFailure(RemoteHconn.java:4931)
    at com.ibm.mq.jmqi.remote.api.RemoteHconn.setReconnectionFailureInner(RemoteHconn.java:2650)
    at com.ibm.mq.jmqi.remote.api.RemoteParentHconn.setReconnectionFailure(RemoteParentHconn.java:152)
    at com.ibm.mq.jmqi.remote.impl.RemoteReconnectThread.bestHconn(RemoteReconnectThread.java:265)
    at com.ibm.mq.jmqi.remote.impl.RemoteReconnectThread.run(RemoteReconnectThread.java:115)
    at com.ibm.msg.client.commonservices.workqueue.WorkQueueItem.runTask(WorkQueueItem.java:319)
    at com.ibm.msg.client.commonservices.workqueue.SimpleWorkQueueItem.runItem(SimpleWorkQueueItem.java:99)
    at com.ibm.msg.client.commonservices.workqueue.WorkQueueItem.run(WorkQueueItem.java:343)
    at com.ibm.msg.client.commonservices.workqueue.WorkQueueManager.runWorkQueueItem(WorkQueueManager.java:312)
    at com.ibm.msg.client.commonservices.j2se.workqueue.WorkQueueManagerImplementation$ThreadPoolWorker.run(WorkQueueManagerImplementation.java:1227)
2020-02-11 09:51:46,969 INFO [Application.run:21] (main) Sending message Hello Testing 17 to MQ server...
2020-02-11 09:51:46,972 ERROR [MQWriter.write:52] (main) Error sending message to write queue
com.ibm.msg.client.jms.DetailedJMSException: JMSWMQ2007: Failed to send a message to destination 'DEV.QUEUE.1'.
JMS attempted to perform an MQPUT or MQPUT1; however IBM MQ reported an error.
Use the linked exception to determine the cause of this error.
    at com.ibm.msg.client.wmq.common.internal.Reason.reasonToException(Reason.java:595)
    at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:215)
    at com.ibm.msg.client.wmq.internal.WMQMessageProducer.checkJmqiCallSuccess(WMQMessageProducer.java:1288)
    at com.ibm.msg.client.wmq.internal.WMQMessageProducer.checkJmqiCallSuccess(WMQMessageProducer.java:1245)
    at com.ibm.msg.client.wmq.internal.WMQMessageProducer.access$800(WMQMessageProducer.java:76)
    at com.ibm.msg.client.wmq.internal.WMQMessageProducer$SpiIdentifiedProducerShadow.sendInternal(WMQMessageProducer.java:906)
    at com.ibm.msg.client.wmq.internal.WMQMessageProducer$ProducerShadow.send(WMQMessageProducer.java:566)
    at com.ibm.msg.client.wmq.internal.WMQMessageProducer.send(WMQMessageProducer.java:1428)
    at com.ibm.msg.client.jms.internal.JmsMessageProducerImpl.sendMessage(JmsMessageProducerImpl.java:855)
    at com.ibm.msg.client.jms.internal.JmsMessageProducerImpl.synchronousSendInternal(JmsMessageProducerImpl.java:2055)
    at com.ibm.msg.client.jms.internal.JmsMessageProducerImpl.sendInternal(JmsMessageProducerImpl.java:1993)
    at com.ibm.msg.client.jms.internal.JmsMessageProducerImpl.send(JmsMessageProducerImpl.java:1486)
    at com.ibm.mq.jms.MQMessageProducer.send(MQMessageProducer.java:293)
    at org.example.MQWriter.write(MQWriter.java:50)
    at org.example.Application.run(Application.java:22)
    at org.example.Application.main(Application.java:13)
Caused by: com.ibm.mq.MQException: JMSCMQ0001: IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2009' ('MQRC_CONNECTION_BROKEN').
    at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:203)
    ... 14 more
Caused by: com.ibm.mq.jmqi.JmqiException: CC=2;RC=2009
    at com.ibm.mq.jmqi.remote.api.RemoteHconn$ReconnectionState.recordFailure(RemoteHconn.java:4931)
    at com.ibm.mq.jmqi.remote.api.RemoteHconn.setReconnectionFailureInner(RemoteHconn.java:2650)
    at com.ibm.mq.jmqi.remote.api.RemoteParentHconn.setReconnectionFailure(RemoteParentHconn.java:152)
    at com.ibm.mq.jmqi.remote.impl.RemoteReconnectThread.bestHconn(RemoteReconnectThread.java:265)
    at com.ibm.mq.jmqi.remote.impl.RemoteReconnectThread.run(RemoteReconnectThread.java:115)
    at com.ibm.msg.client.commonservices.workqueue.WorkQueueItem.runTask(WorkQueueItem.java:319)
    at com.ibm.msg.client.commonservices.workqueue.SimpleWorkQueueItem.runItem(SimpleWorkQueueItem.java:99)
    at com.ibm.msg.client.commonservices.workqueue.WorkQueueItem.run(WorkQueueItem.java:343)
    at com.ibm.msg.client.commonservices.workqueue.WorkQueueManager.runWorkQueueItem(WorkQueueManager.java:312)
    at com.ibm.msg.client.commonservices.j2se.workqueue.WorkQueueManagerImplementation$ThreadPoolWorker.run(WorkQueueManagerImplementation.java:1227)

Обновление вопроса от 12 февраля 2020 года

Добавлен этот образец и выводы, основанные на ответе JoshM c от 11 февраля 2020 года. Мои комментарии к этому образцу:

  • Сейчас я использую классы MQ * и задаю параметры переподключения, как предложено.
  • Переподключение все еще не происходит, хотя

MQWriter2. java

public class MQWriter2 {

    private static final Logger LOGGER = LoggerFactory.getLogger(MQWriter2.class);

    private Connection connection = null;
    private Session session = null;
    private Queue destination = null;
    private MessageProducer producer = null;

    public MQWriter2() {
        try {
            MQConnectionFactory factory = new MQConnectionFactory();
            factory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
            factory.setConnectionNameList("XXX.XXX.XXX.XXX(1414)");
            factory.setQueueManager(MQConnectionDetails.QM_NAME);
            factory.setChannel(MQConnectionDetails.CHANNEL);
            factory.setClientReconnectOptions(WMQConstants.WMQ_CLIENT_RECONNECT);
            factory.setClientReconnectTimeout(MQConnectionDetails.RECONNECT_TIMEOUT);

            LOGGER.info("Initializing connection to write queue {} on {}:{}...",
                    MQConnectionDetails.QUEUE,
                    MQConnectionDetails.HOST,
                    MQConnectionDetails.PORT);
            connection = factory.createConnection();
            connection.setExceptionListener(new MQExceptionListener());
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            destination = session.createQueue(MQConnectionDetails.QUEUE);
            producer = session.createProducer(destination);
            connection.start();
        } catch (JMSException ex) {
            LOGGER.error("Error initializing connection to write queue", ex);
        }
    }

    public void write(String message) {
        try {
            TextMessage textMessage = session.createTextMessage(message);
            producer.send(textMessage);
        } catch (Exception ex) {
            LOGGER.error("Error sending message to write queue", ex);
        }
    }
}

Консольный вывод

2020-02-12 08:39:11,628 INFO [MQWriter2.<init>:29] (main) Initializing connection to write queue DEV.QUEUE.1 on 54.161.121.207:1414...
2020-02-12 08:39:14,552 INFO [Application.run:19] (main) Sending message Hello Testing 1 to MQ server...
2020-02-12 08:39:15,710 INFO [Application.run:19] (main) Sending message Hello Testing 2 to MQ server...
2020-02-12 08:39:16,841 INFO [Application.run:19] (main) Sending message Hello Testing 3 to MQ server...
...
2020-02-12 08:39:41,973 INFO [Application.run:19] (main) Sending message Hello Testing 25 to MQ server...
2020-02-12 08:41:27,314 ERROR [MQExceptionListener.onException:14] (JMSCCThreadPoolWorker-10) =====
2020-02-12 08:41:27,314 ERROR [MQExceptionListener.onException:15] (JMSCCThreadPoolWorker-10) com.ibm.msg.client.jms.DetailedJMSException: JMSWMQ1107: A problem with this connection has occurred.
An error has occurred with the IBM MQ JMS connection.
Use the linked exception to determine the cause of this error.
2020-02-12 08:41:27,314 ERROR [MQWriter2.write:49] (main) Error sending message to write queue
com.ibm.msg.client.jms.DetailedJMSException: JMSWMQ2007: Failed to send a message to destination 'DEV.QUEUE.1'.
JMS attempted to perform an MQPUT or MQPUT1; however IBM MQ reported an error.
Use the linked exception to determine the cause of this error.
    at com.ibm.msg.client.wmq.common.internal.Reason.reasonToException(Reason.java:595)
    at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:215)
    at com.ibm.msg.client.wmq.internal.WMQMessageProducer.checkJmqiCallSuccess(WMQMessageProducer.java:1288)
    at com.ibm.msg.client.wmq.internal.WMQMessageProducer.checkJmqiCallSuccess(WMQMessageProducer.java:1245)
    at com.ibm.msg.client.wmq.internal.WMQMessageProducer.access$800(WMQMessageProducer.java:76)
    at com.ibm.msg.client.wmq.internal.WMQMessageProducer$SpiIdentifiedProducerShadow.sendInternal(WMQMessageProducer.java:906)
    at com.ibm.msg.client.wmq.internal.WMQMessageProducer$ProducerShadow.send(WMQMessageProducer.java:566)
    at com.ibm.msg.client.wmq.internal.WMQMessageProducer.send(WMQMessageProducer.java:1428)
    at com.ibm.msg.client.jms.internal.JmsMessageProducerImpl.sendMessage(JmsMessageProducerImpl.java:855)
    at com.ibm.msg.client.jms.internal.JmsMessageProducerImpl.synchronousSendInternal(JmsMessageProducerImpl.java:2055)
    at com.ibm.msg.client.jms.internal.JmsMessageProducerImpl.sendInternal(JmsMessageProducerImpl.java:1993)
    at com.ibm.msg.client.jms.internal.JmsMessageProducerImpl.send(JmsMessageProducerImpl.java:1486)
    at com.ibm.mq.jms.MQMessageProducer.send(MQMessageProducer.java:293)
    at org.example.MQWriter2.write(MQWriter2.java:47)
    at org.example.Application.run(Application.java:20)
    at org.example.Application.main(Application.java:11)
Caused by: com.ibm.mq.MQException: JMSCMQ0001: IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2009' ('MQRC_CONNECTION_BROKEN').
    at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:203)
    ... 14 more
Caused by: com.ibm.mq.jmqi.JmqiException: CC=2;RC=2009
    at com.ibm.mq.jmqi.remote.api.RemoteHconn$ReconnectionState.recordFailure(RemoteHconn.java:4931)
    at com.ibm.mq.jmqi.remote.api.RemoteHconn.setReconnectionFailureInner(RemoteHconn.java:2650)
    at com.ibm.mq.jmqi.remote.api.RemoteParentHconn.setReconnectionFailure(RemoteParentHconn.java:152)
    at com.ibm.mq.jmqi.remote.impl.RemoteReconnectThread.bestHconn(RemoteReconnectThread.java:265)
    at com.ibm.mq.jmqi.remote.impl.RemoteReconnectThread.run(RemoteReconnectThread.java:115)
    at com.ibm.msg.client.commonservices.workqueue.WorkQueueItem.runTask(WorkQueueItem.java:319)
    at com.ibm.msg.client.commonservices.workqueue.SimpleWorkQueueItem.runItem(SimpleWorkQueueItem.java:99)
    at com.ibm.msg.client.commonservices.workqueue.WorkQueueItem.run(WorkQueueItem.java:343)
    at com.ibm.msg.client.commonservices.workqueue.WorkQueueManager.runWorkQueueItem(WorkQueueManager.java:312)
    at com.ibm.msg.client.commonservices.j2se.workqueue.WorkQueueManagerImplementation$ThreadPoolWorker.run(WorkQueueManagerImplementation.java:1227)

Ответы [ 2 ]

5 голосов
/ 28 января 2020

Вы можете установить ExceptionListener для объекта соединения после создания соединения. Метод onException в ExceptionListener вызывается при попытке повторного подключения. Вот пример:

    ExceptionListener exceptionListener = new ExceptionListener(){
        @Override
        public void onException(JMSException e) {
            System.out.println(e);
            if(e.getLinkedException() != null)
                System.out.println(e.getLinkedException());
        }
    };
    MQQueueConnection connection = (MQQueueConnection) cf.createQueueConnection();
    connection.setExceptionListener(exceptionListener);
0 голосов
/ 11 февраля 2020

Несколько моментов, которые могут вам помочь.

В следующей строке задается время, в течение которого MQ будет пытаться повторно подключиться к администратору очередей, когда обнаружит, что соединение потеряно.

jcf.setIntProperty(WMQConstants.WMQ_CLIENT_RECONNECT_TIMEOUT, MQConnectionDetails.RECONNECT_TIMEOUT);

Сколько времени потребуется клиенту, чтобы заметить, что соединение разорвано, зависит от типа сбоя, но в описываемой вами ситуации оно будет основано на параметре HBINT канала SVRCONN в очереди. manager.

Сердцебиение посылается каждые HBINT секунд, когда никакой другой обычный трафик c не передается по каналу. TIMEOUT канала основывается на HBINT, если HBINT меньше 60 секунд, тогда TIMEOUT вдвое больше HBINT, если HBINT 60 секунд или больше, TIMEOUT равен HBINT плюс 60 секунд. Время ожидания основано на последнем трафике c или когда был послан сигнал сердцебиения, а не при изменении конфигурации брандмауэра, хотя в этом случае кажется, что вы отправляете сообщение каждую секунду, поэтому оно должно было быть близко.

Основываясь на журналах, я не уверен, что он выбирает опцию RECONNECT, как я ожидаю, когда истечет время ожидания повторного подключения, что вы получите одну из этих ошибок вместо MQRC_CONNECTION_BROKEN:

  • MQRC_RECONNECT_FAILED
  • MQRC_RECONNECT_TIMED_OUT

В образцах, которые я имею, я установил это так, возможно, попробуйте это вместо того, как вы сейчас его устанавливаете:

jcf.setClientReconnectOptions(WMQConstants.WMQ_CLIENT_RECONNECT);
jcf.setClientReconnectTimeout(MQConnectionDetails.RECONNECT_TIMEOUT);

Исходя из того, что я вижу, я полагаю, что для вашего HBINT установлено значение 45 секунд на канале SVRCONN, и соединение просто прерывается с MQRC_CONNECTION_BROKEN на 90 секунд и никогда не пытается восстановить соединение.

...