【发布时间】:2017-09-17 11:08:18
【问题描述】:
我的基于 Apache-camel 的应用程序正在使用来自 IBM 队列之一的消息,例如以下是连接工厂的详细信息
hostname=host1000
QManager=QM1000
Port="some port"
Channel="common channel"
Camel 流消费和处理并将来自消息头的响应发送到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
我得到以下异常
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').
Update-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); */
}
【问题讨论】:
-
targetClient=1 表示 JMS 不应为 JMS 标头添加 IBM MQ 类(称为 RFH2 标头),换句话说,远程应用程序可能不是 JMS 应用程序。您是否可能需要在 Camel 流程中以不同的方式指定它?
-
您所拥有的 URI 减去 wmq:// 是您如何将特定队列管理器上的队列指定给 IBM MQ JMS 类。我不熟悉骆驼来帮助你更多。如果 MQ 7.0 或更早版本不受支持,或者在 MQ 7.1 及更高版本中,您需要获得 SCTQ 的权限,您可以提供对特定远程队列管理器的 rqmname 的权限。
-
您只需连接到使用原始消息的同一个队列管理器,并通过您指定的 URL 发送它。只要您连接到的队列管理器是另一个队列管理器所在的集群的一部分,并且您拥有适当的权限,就可以发送它。您只需要连接到的队列管理器的连接详细信息,因为您不会直接连接到其他队列管理器。
-
在对 Camel 进行任何操作之前,我建议您在与 Camel 相同的主机上测试您的 uri 以及使用 RFHUTIL 将消息发送到 MQ 集群。如果你成功了,那么 MQ 的东西就会按预期工作。 Camel 的 URI 应该遵循 MQ uri 模式。但首先让它与 RFHUTIL 一起工作。
-
在您的第一个示例中,QM1000 是您从中读取请求消息的队列管理器,而 QM1012 是回复队列所在的位置?如果是这种情况,则应将回复消息放入 queue://QM1012/QUEUE_V1,但您的连接仍将是 QM1000。 @SoucianceEqdamRashti 建议是验证 URI 是否正确的绝佳方法。
标签: java apache-camel ibm-mq