我不确定自己在做什么错,这个问题非常零星,我有下面的代码在IBM MQ上发送JMS消息。我正在单独的read usign spring @async中进行操作,如下所示。
@Override
@Async
public void crewSeqAssignOrRemoveBatch(List<Batch> oBatchFosRequestList, String transactionType) throws InterruptedException {
long lStartTime = Instant.now().toEpochMilli();
logger.info("In Seperate Thread for FOS Submissoin, Thread Name is " + Thread.currentThread().getId() + ":"+Thread.currentThread().getName()+":"+Thread.currentThread().getThreadGroup()+":"+Thread.currentThread().activeCount()+":"+Thread.currentThread().getState());
logger.info("FHSeqAssignOrRemoveServiceImpl : crewSeqAssignOrRemoveBatch() : Start >>");
try
{
for (Iterator<Batch> iterator = oBatchFosRequestList.iterator(); iterator.hasNext();) {
Batch oBatchFosRequest = iterator.next();
UUID uniqueId = UUID.randomUUID();
String correlationId = uniqueId.toString() + "-" + oBatchFosRequest.getTransactionID() +"-"+ Calendar.getInstance().getTimeInMillis();
logger.info("correlationId generated is :" + correlationId);
try {
//JMSTextMessage message = null;
logger.info("Executing MessageCreator for ID "+ oBatchFosRequest.getTransactionID() +" on :" + new Date().toString());
MessageCreator mc = new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
JMSTextMessage message = null;
try {
logger.info("Executing CreateMessage for ID "+ oBatchFosRequest.getTransactionID() +" on :" + new Date().toString());
//POINT 2
logger.info("Session Object ........ " + session.toString());
logger.info("Session Status - Is Session Transacted ?........ " + session.getTransacted());
logger.info("Session Status acknowledge mode........ " + session.getAcknowledgeMode());
logger.info("Ready to send message........ ");
logger.info("Send ConnectionFactory is: " + jmsQueueTemplate.getConnectionFactory().toString());
logger.info("Send destination is: " + jmsQueueTemplate.getDefaultDestination());
logger.info("Reply destination is: " + destination);
logger.info("Sent message correlationId is: " + correlationId);
logger.info("##########################################################");
message = (JMSTextMessage) session.createTextMessage();
String fosXmlBatchRequest = XMLUtil.createBatchFosRequestXML(oBatchFosRequest);
message.setText(fosXmlBatchRequest);
message.setJMSCorrelationID(correlationId);
logger.info(transactionType + " : Sending message is:");
logger.info(message.getText());
logger.info("##########################################################");
message.setJMSReplyTo(destination);
} catch (JMSException je) {
Exception ex = je.getLinkedException();
logger.info("JMS Linked Exception Occured :" + ex.getMessage());
ex.printStackTrace();
logger.info("JMS Exception Occured :" + je.getMessage());
je.printStackTrace();
}
catch (Exception e) {
logger.info("Exception Occured :" + e.getMessage());
e.printStackTrace();
}
return message;
}
};
logger.info("Executing send for ID "+ oBatchFosRequest.getTransactionID() +" on :" + new Date().toString());
logger.info("Calling Send Method ");
jmsQueueTemplate.send(mc);
logger.info("Send Completed");
我的JMS配置如下:
import javax.jms.Destination;
import javax.jms.JMSException;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.jms.connection.CachingConnectionFactory;
import org.springframework.jms.connection.SingleConnectionFactory;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.listener.DefaultMessageListenerContainer;
import org.springframework.jms.support.converter.MappingJackson2MessageConverter;
import org.springframework.jms.support.converter.MessageConverter;
import org.springframework.jms.support.converter.MessageType;
import org.springframework.stereotype.Component;
import com.ibm.mq.jms.MQQueue;
import com.ibm.mq.jms.MQQueueConnectionFactory;
@Configurable
@Component
public class JMSConfiguration {
private final Logger log = LogManager.getLogger(JMSConfiguration.class);
@Autowired
MessageListenerReciever messageListenerReciever1;
@Autowired
MessageListenerReciever messageListenerReciever2;
private String hostName1;
private String hostName2;
private String hostName3;
private String writePort;
private String readPort;
private String channel;
private String transportType;
private String updateQueue;
private String replyQueue;
private String queueGateway;
@Autowired
JMSConfiguration(Environment environment){
this.hostName1 = environment.getRequiredProperty("jms.cf.write.hostName1");
this.hostName2 = environment.getRequiredProperty("jms.cf.read.hostName2");
this.hostName3 = environment.getRequiredProperty("jms.cf.read.hostName3");
this.writePort = environment.getRequiredProperty("jms.cf.write.port");
this.readPort = environment.getRequiredProperty("jms.cf.read.port");
this.channel = environment.getRequiredProperty("jms.cf.channel");
this.transportType = environment.getRequiredProperty("jms.cf.transportType");
this.updateQueue = environment.getRequiredProperty("jms.queue.update");
this.replyQueue = environment.getRequiredProperty("jms.queue.reply");
this.queueGateway = environment.getRequiredProperty("jms.queue.gateway");
}
@Bean
public MQQueueConnectionFactory connectionFactory1() {
MQQueueConnectionFactory connectionFactory = new MQQueueConnectionFactory();
try {
connectionFactory.setHostName(hostName1);
connectionFactory.setPort(Integer.parseInt(writePort));
connectionFactory.setChannel(channel);
connectionFactory.setTransportType(Integer.parseInt(transportType));
} catch (NumberFormatException | JMSException e) {
log.error(e.toString(),e);
}
return connectionFactory;
}
@Bean
@Primary
public CachingConnectionFactory cachingConnectionFactory(MQQueueConnectionFactory connectionFactory) {
CachingConnectionFactory oCachingConnectionFactory = new CachingConnectionFactory();
oCachingConnectionFactory.setTargetConnectionFactory(connectionFactory);
//oCachingConnectionFactory.setCacheProducers(true);
oCachingConnectionFactory.setSessionCacheSize(100);
oCachingConnectionFactory.setReconnectOnException(true);
return oCachingConnectionFactory;
}
public MQQueueConnectionFactory connectionFactory2() {
MQQueueConnectionFactory connectionFactory = new MQQueueConnectionFactory();
try {
connectionFactory.setHostName(hostName2);
connectionFactory.setPort(Integer.parseInt(readPort));
connectionFactory.setChannel(channel);
connectionFactory.setTransportType(Integer.parseInt(transportType));
} catch (NumberFormatException | JMSException e) {
log.error(e.toString(),e);
}
return connectionFactory;
}
public MQQueueConnectionFactory connectionFactory3() {
MQQueueConnectionFactory connectionFactory = new MQQueueConnectionFactory();
try {
connectionFactory.setHostName(hostName3);
connectionFactory.setPort(Integer.parseInt(readPort));
connectionFactory.setChannel(channel);
connectionFactory.setTransportType(Integer.parseInt(transportType));
} catch (NumberFormatException | JMSException e) {
log.error(e.toString(),e);
}
return connectionFactory;
}
@Bean
public Destination jmsDestinationResolverSender() throws JMSException {
return new MQQueue(updateQueue);
}
@Bean
public Destination jmsDestinationResolverReceiver() throws JMSException {
return new MQQueue(replyQueue);
}
@Bean
public Destination jmsDestinationResolverReplyTo() throws JMSException {
return new MQQueue(queueGateway, replyQueue);
}
@Bean
public JmsTemplate jmsQueueTemplate(SingleConnectionFactory oSingleConnectionFactory) throws JMSException {
JmsTemplate jmsTemplate = new JmsTemplate();
jmsTemplate.setConnectionFactory(oSingleConnectionFactory);
jmsTemplate.setDefaultDestination(jmsDestinationResolverSender());
jmsTemplate.afterPropertiesSet();
log.info("in jms configuration ConnectionFactory is:" + jmsTemplate.getConnectionFactory());
log.info("in jms configuration Send destination is:" + jmsTemplate.getDefaultDestination());
log.info("in jms configuration Send Delivery Delay is :" + jmsTemplate.getDeliveryDelay());
log.info("in jms configuration Send Delivery Mode is:" + jmsTemplate.getDeliveryMode());
return jmsTemplate;
}
@Bean
public DefaultMessageListenerContainer listenerContainer() throws JMSException {
DefaultMessageListenerContainer defMsgListCont = new DefaultMessageListenerContainer();
defMsgListCont.setConnectionFactory(connectionFactory3());
defMsgListCont.setDestination(jmsDestinationResolverReceiver());
defMsgListCont.setMessageListener(messageListenerReciever1);
defMsgListCont.afterPropertiesSet();
return defMsgListCont;
}
@Bean
public DefaultMessageListenerContainer listenerContainer2() throws JMSException {
DefaultMessageListenerContainer defMsgListCont = new DefaultMessageListenerContainer();
defMsgListCont.setConnectionFactory(connectionFactory2());
defMsgListCont.setDestination(jmsDestinationResolverReceiver());
defMsgListCont.setMessageListener(messageListenerReciever2);
defMsgListCont.afterPropertiesSet();
return defMsgListCont;
}
// Serialize message content to json using TextMessage
@Bean
public MessageConverter jacksonJmsMessageConverter() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setTargetType(MessageType.TEXT);
converter.setTypeIdPropertyName("_type");
return converter;
}
}
我不确定问题出在哪里,但是我坚信它与我正在使用的连接工厂有关,我正尝试使用CachingConnectionFactory,但是在低于mentioend配置的情况下,该行不断出现以下代码异常,从而偶尔失败>
jmsQueueTemplate.send(mc);
以下例外:
> 12-12-2018 09:05:27.153 INFO htappp22 --- [ FAPS-FOS-5] c.a.f.s.FHSeqAssignOrRemoveServiceImpl : JMSException while Sending Message To FOS Outside
org.springframework.jms.UncategorizedJmsException: Uncategorized exception occurred during JMS processing; nested exception is javax.jms.JMSException: MQJMS2007: failed to send message to MQ queue; nested exception is com.ibm.mq.MQException: MQJE001: Completion Code 2, Reason 2009
at org.springframework.jms.support.JmsUtils.convertJmsAccessException(JmsUtils.java:316)
at org.springframework.jms.support.JmsAccessor.convertJmsAccessException(JmsAccessor.java:169)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:487)
at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:559)
at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:550)
at com.aa.faps.services.FHSeqAssignOrRemoveServiceImpl.crewSeqAssignOrRemoveBatch(FHSeqAssignOrRemoveServiceImpl.java:115)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.interceptor.AsyncExecutionInterceptor$1.call(AsyncExecutionInterceptor.java:115)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: javax.jms.JMSException: MQJMS2007: failed to send message to MQ queue
at com.ibm.mq.jms.services.ConfigEnvironment.newException(ConfigEnvironment.java:567)
at com.ibm.mq.jms.MQMessageProducer.sendInternal(MQMessageProducer.java:1743)
at com.ibm.mq.jms.MQMessageProducer.send(MQMessageProducer.java:1056)
at org.springframework.jms.connection.CachedMessageProducer.send(CachedMessageProducer.java:181)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.jms.connection.CachedMessageProducer$Jms2MessageProducerInvocationHandler.invoke(CachedMessageProducer.java:293)
at com.sun.proxy.$Proxy276.send(Unknown Source)
at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:626)
at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:597)
at org.springframework.jms.core.JmsTemplate$3.doInJms(JmsTemplate.java:562)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:484)
... 15 more