我基于Apache骆驼的应用正在消耗来自IBM队列之一的消息,例如下面是连接工厂的详细信息
hostname=host1000 QManager=QM1000 Port="some port" Channel="common channel"
消耗和处理并将响应发送到来自消息头的ReplyQueue的骆驼流。
from(wmq:queue:<INPUT_QUEUE>) .bean("processBean") .bean("beanToSendMsgToReplyQueue")
在骆驼标头中,我在JMSReplyQueue下面。您可以看到它是不同的队列管理器,并且该队列管理器来自不同的主机,但是在集群环境中。
JMSReplyTo = queue://QM1012/TEST.REPLY?targetClient=1
队列管理器也在两者之间。喜欢
queue://<queue-manager>//<queue-name>?<other parameters>
以下是我在发送消息时遇到的异常。
ERROR o.apache.camel.processor.DefaultErrorHandler:215 - Failed delivery for (MessageId: ID-xxxxxxxxx-0-4 on ExchangeId: ID-xxxxxx-42443-1492594420697-0-1). Exhausted after delivery attempt: 1 caught: org.apache.camel.ResolveEndpointFailedException: Failed to resolve endpoint: wmq://queue://QM1012/TEST.REPLY?targetClient=1 due to: Failed to resolve endpoint: wmq://queue://TAP2001R5/TEST?targetClient=1 due to: There are 1 parameters that couldn't be set on the endpoint. Check the uri if the parameters are spelt correctly and that they are properties of the endpoint. Unknown parameters=[{targetClient=1}]. Processed by failure processor: FatalFallbackErrorHandler[Pipeline[[Channel[sendTo(Endpoint[wmq://queue:BACKOUT_Q])], Channel[DelegateSync[com.xxx.yyy.listener.XXXOnExceptionProcessor@21c66ee4]], Channel[Stop]]]]
任何人都可以帮助我将消息发送到不同主机中的不同队列管理器队列,但它们都在同一群集中。另外,队列管理器名称位于字符串的中间,因此如何解决该问题。如果您需要更多详细信息,请告诉我。
更新-1: 尝试使用相同的队列管理器且没有参数
JMSReplyTo = queue://QM1000/QUEUE_V1 低于异常我正在
JMSReplyTo = queue://QM1000/QUEUE_V1
org.springframework.jms.InvalidDestinationException: JMSWMQ2008: Failed to open MQ queue 'QM1000/QUEUE_V1'.; nested exception is com.ibm.msg.client.jms.DetailedInvalidDestinationException: JMSWMQ2008: Failed to open MQ queue 'QM1000/QUEUE_V1'. JMS attempted to perform an MQOPEN, but WebSphere MQ reported an error. Use the linked exception to determine the cause of this error. Check that the specified queue and queue manager are defined correctly.; nested exception is com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2189' ('MQRC_CLUSTER_RESOLUTION_ERROR').
更新2
我可以使用普通的javax.jms。和com.ibm.mq.jms。 api将消息发送到JMSReplyTo,但不能通过Apache骆驼发送。Camel用户/开发人员小组的任何人都可以帮助我使用骆驼组件来处理相同的事情。
@Override public void process(Exchange exchange) throws Exception { QueueConnection m_connection = this.connectionFactory.createQueueConnection(); //m_connection.start(); boolean transacted = false; QueueSession session = m_connection.createQueueSession(transacted, QueueSession.AUTO_ACKNOWLEDGE); TextMessage outMessage = session.createTextMessage(); outMessage.setText(exchange.getIn().getBody()); MQQueue mq = new MQQueue( "queue://QM1012/TEST.REPLY"); QueueSender queueSender = session.createSender((MQQueue) mq); queueSender.send(outMessage); /* producerTemplate.send("wmq:" + "queue://QM1012/TEST.REPLY", exchange); */ }
首先,感谢大家的支持。我的用例如下(上面也有)。
使用Apache Camel连接到MQ主机(主机名,queueManager,端口,通道),并使用属于同一主机/ Qmanager的队列中的消息。消息带有ReplyToQueue(JMSReplyTo)标头值。ReplyToQueue(JMSReplyTo)的值如下 例如 queue://Different_QueueManager_in_Cluster/TEST.REPLY?mdReadEnabled=true&messageBody=0&mdWriteEnabled=true&XMSC_WMQ_REPLYTO_STYLE=1&targetClient=1
使用Apache Camel连接到MQ主机(主机名,queueManager,端口,通道),并使用属于同一主机/ Qmanager的队列中的消息。消息带有ReplyToQueue(JMSReplyTo)标头值。ReplyToQueue(JMSReplyTo)的值如下
例如
queue://Different_QueueManager_in_Cluster/TEST.REPLY?mdReadEnabled=true&messageBody=0&mdWriteEnabled=true&XMSC_WMQ_REPLYTO_STYLE=1&targetClient=1
现在的问题是,当连接对象连接到上述主机和队列管理器时,如何使用不同的队列管理器将回复消息发送到不同的队列。
注意:所有MQ队列管理器都在集群环境中。
解决方案1: 例如
form(wmq:queue:INPUT_MSG_Q) .bean(requestProcessor) .bean(responseProcessor)
默认情况下,Apache Camel处理ReplyToQ(JMSReplyTo)。如果您不想发送对ReplyToQ(JMSReplyTo)的回复,请disableReplyTo=true在消费时使用
disableReplyTo=true
注意:在queue://Different_QueueManager_in_Cluster/TEST.REPLY使用相同的连接/连接工厂发送到时,MQ集群将检查消息是否必须通过集群中的指定队列发送到指定的队列管理器。关于以下参数 ?mdReadEnabled=true&messageBody=0&mdWriteEnabled=true&XMSC_WMQ_REPLYTO_STYLE=1&targetClient=1,Apache Camel能够在自动回复时自动解析,而无需使用任何第三方解析器JMSReplyTo。
queue://Different_QueueManager_in_Cluster/TEST.REPLY
?mdReadEnabled=true&messageBody=0&mdWriteEnabled=true&XMSC_WMQ_REPLYTO_STYLE=1&targetClient=1
JMSReplyTo
解决方案2:
使用禁用自动回复disableReplyTo=true并从标头中获取队列详细信息,并使用纯javax.jms。和com.ibm.mq.jms。 api发送消息。代码如下。
@Override public void process(Exchange exchange) throws Exception { QueueConnection m_connection = this.connectionFactory.createQueueConnection(); //m_connection.start(); boolean transacted = false; QueueSession session = m_connection.createQueueSession(transacted, QueueSession.AUTO_ACKNOWLEDGE); TextMessage outMessage = session.createTextMessage(); outMessage.setText(exchange.getIn().getBody()); MQQueue mq = new MQQueue( "queue://Different_QueueManager_in_Cluster/TEST.REPLY"); QueueSender queueSender = session.createSender((MQQueue) mq); queueSender.send(outMessage); /* producerTemplate.send("wmq:" + "queue://Different_QueueManager_in_Cluster/TEST.REPLY", exchange); */ }
对于参数,请使用@Sebastian Brandt提到的目标解析器(发布)