IBM MQ:在启动后出现连接错误的情况下重新连接到消息代理
IBM MQ: reconnect to message broker in case of connection error after startup
我正在尝试在 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);
}
一切正常。然后我关闭了互联网,这段代码开始抛出错误——说队列连接不可用。我将我的系统连接回互联网,它又开始发送消息。凉爽的!它如我所愿。
我尝试使用带有 javaContext 实现的 JMS2.0 重复相同的实验。这是我的第二个实现 -
@Bean("jmsContext")
public JMSContext createProducer(@Qualifier("jmsConnectionFactory") ConnectionFactory cf) {
return cf.createContext();
}
@Bean("jmsProducer")
public JMSProducer createProducer(@Qualifier("jmsContext") JMSContext jmsContext) {
return jmsContext.createProducer();
}
同样,与上一种方法类似,我创建了一个调度程序来发布这样的消息 -
@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());
}
}
在这里,我也可以发送消息。很好,直到现在。我的问题出现在以下部分。
调度程序是 运行,我断开了我的系统与互联网的连接,代码抛出错误说没有连接。我重新连接了我的系统,但我的消息仍然没有发送到代理(与之前的实现不同)。不是应该回连发消息吗?
我在第二次实施中遗漏了什么?
请注意: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').
如果您希望底层 MQ 客户端代码在失败时重新连接,您将需要像这样启用 MQ 自动重新连接:
cf.setClientReconnectOptions(WMQConstants.WMQ_CLIENT_RECONNECT);
cf.setClientReconnectTimeout(1800); // how long in seconds to continue to attempt reconnection before failing
我正在尝试在 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);
}
一切正常。然后我关闭了互联网,这段代码开始抛出错误——说队列连接不可用。我将我的系统连接回互联网,它又开始发送消息。凉爽的!它如我所愿。
我尝试使用带有 javaContext 实现的 JMS2.0 重复相同的实验。这是我的第二个实现 -
@Bean("jmsContext")
public JMSContext createProducer(@Qualifier("jmsConnectionFactory") ConnectionFactory cf) {
return cf.createContext();
}
@Bean("jmsProducer")
public JMSProducer createProducer(@Qualifier("jmsContext") JMSContext jmsContext) {
return jmsContext.createProducer();
}
同样,与上一种方法类似,我创建了一个调度程序来发布这样的消息 -
@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());
}
}
在这里,我也可以发送消息。很好,直到现在。我的问题出现在以下部分。 调度程序是 运行,我断开了我的系统与互联网的连接,代码抛出错误说没有连接。我重新连接了我的系统,但我的消息仍然没有发送到代理(与之前的实现不同)。不是应该回连发消息吗?
我在第二次实施中遗漏了什么?
请注意: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').
如果您希望底层 MQ 客户端代码在失败时重新连接,您将需要像这样启用 MQ 自动重新连接:
cf.setClientReconnectOptions(WMQConstants.WMQ_CLIENT_RECONNECT);
cf.setClientReconnectTimeout(1800); // how long in seconds to continue to attempt reconnection before failing