IBM MQ: переподключиться к брокеру сообщений в случае ошибки соединения после запуска - PullRequest
0 голосов
/ 08 января 2020

Я пытаюсь опубликовать sh сообщений в очереди IBM MQ. Вот моя реализация -

@Bean("jmsTemplate")
public JmsTemplate createProducer(@Qualifier("jmsConnectionFactory") ConnectionFactory cf) {
    JmsTemplate jmsTemplate = new JmsTemplate(cf);
    jmsTemplate.setDefaultDestinationName("my-queue-name");
    return jmsTemplate;
}

, а затем я вызываю ее в планировщике для создания сообщения каждую секунду -

@Autowired @Qualifier("jmsTemplate") JmsTemplate jmsTemplate;

@Scheduled(fixedDelayString = "1000")
public void runOnStart() {
    String message = "sample message "+String.valueOf(System.currentTimeMillis());
    jmsTemplate.convertAndSend(message);
    LOGGER.info(message);
}

Все работает хорошо. Затем я отключил inte rnet, и этот фрагмент кода начал выдавать ошибку - говоря, что подключение к очереди недоступно. Я подключил свою систему обратно к inte rnet, и она снова начала отправлять сообщения. Круто! Это сработало, как я хотел.

Я попытался повторить тот же эксперимент, используя JMS2.0 с реализацией javaContext. Вот моя вторая реализация -

@Bean("jmsContext")
public JMSContext createProducer(@Qualifier("jmsConnectionFactory") ConnectionFactory cf) {
    return cf.createContext();
}
@Bean("jmsProducer")
public JMSProducer createProducer(@Qualifier("jmsContext") JMSContext jmsContext) {
    return jmsContext.createProducer();
}

Снова, как и в предыдущем подходе, я создал планировщик для публикации sh сообщений, подобных этому -

@Autowired @Qualifier("jmsContext") JMSContext jmsContext;
@Autowired @Qualifier("jmsProducer") JMSProducer jmsProducer;

@Scheduled(fixedDelayString = "1000")
public void runOnStart() {
    try {
        Destination destination = this.jmsContext.createQueue("my-queue-name"));
        String message = "sample message "+String.valueOf(System.currentTimeMillis());
        this.jmsProducer.send(destination, message);
    } catch (JMSException e) {
        LOGGER.error("Error in sending message", e.getLinkedException());
    }
}

Здесь также я могу отправлять сообщения. Очень хорошо до сих пор. Моя проблема возникает в следующей части. Планировщик работал, я отключил мою систему от inte rnet, и код выдает ошибку, сообщающую, что нет соединения. Я снова подключил свою систему, но мои сообщения все еще не отправлялись брокеру (в отличие от предыдущей реализации). Разве он не должен соединяться и отправлять сообщения?

Что я пропустил во второй реализации?

Обратите внимание, что: Bean @Qualifier("jmsConnectionFactory") ConnectionFactory cf одинаков для обеих реализаций и похож на -

public static ConnectionFactory getMQConnectionFactory (
        Map<String, String> queueDetails,
        SSLContext sslContext) throws Exception {
    MQConnectionFactory cf = new MQConnectionFactory();
    cf.setHostName(queueDetails.get("hostname"));
    cf.setPort(Integer.parseInt(queueDetails.get("port")));
    cf.setQueueManager(queueDetails.get("queueManager"));
    cf.setChannel(queueDetails.get("channel"));
    cf.setTransportType(WMQConstants.WMQ_CM_CLIENT);
    cf.setStringProperty(WMQConstants.USERID, queueDetails.get("username"));
    cf.setSSLCipherSuite(queueDetails.get("sslCipherSuite"));
    cf.setSSLSocketFactory(sslContext.getSocketFactory());
    return cf;
}

Исключение -

com.ibm.mq.MQException: JMSCMQ0001: IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2009' ('MQRC_CONNECTION_BROKEN').

1 Ответ

2 голосов
/ 08 января 2020

Если вы хотите, чтобы базовый клиентский код MQ переподключался при сбое, вам нужно включить автоматическое переподключение mq так:

cf.setClientReconnectOptions(WMQConstants.WMQ_CLIENT_RECONNECT);
cf.setClientReconnectTimeout(1800); // how long in seconds to continue to attempt reconnection before failing 
...