繁体   English   中英

使用JMS应用程序无法从IBM MQ获得响应

[英]Not able to get response from IBM MQ using JMS application

我们使用请求/答复方式的IBM MQ与第三方进行通信。 我们向他们发送请求,他们给我们答复。 当前,我们两个都有一个基于Java的简单本机IBM MQ应用程序。 我们计划使用spring jms重写我们的代码。 但是当使用spring jms时,在给定的时间内我们没有得到任何响应。 我们正在使用JMSTemplate发送或接收消息。 我正在分享我的代码段。 我在这里做错什么吗? 我应该在这里设置其他属性吗?

  // Request Part (we are sending request)

  String request // this is the request string
  byte[] reqData = request.getBytes(); // converting it into byte array to send

  TextMessage txtMsg = session.createTextMessage(String.valueOf(reqData));

  Destination replyToQName = jmsTemplate.getDestinationResolver().resolveDestinationName(session, responseQueueName, false);

  txtMsg.setJMSReplyTo(replyToQName);

  Destination requestQ = jmsTemplate.getDestinationResolver().resolveDestinationName(session, requestQueueName, false);

  ((JmsDestination) requestQ).setBooleanProperty( WMQConstants.WMQ_MQMD_WRITE_ENABLED, true );

  ((MQQueue) requestQ).setTargetClient(WMQConstants.WMQ_CLIENT_NONJMS_MQ); // setting this because third party application is native websphere mq java application 

  jmsTemplate.convertAndSend(requestQ, txtMsg);

  // saved msgId of request for late use
  String messageId =  txtMsg.getJMSMessageID();


  // Response fetching part

  Destination responseQ = jmsTemplate.getDestinationResolver().resolveDestinationName(session, responseQueueName, false);

  ((JmsDestination) responseQ).setBooleanProperty(WMQConstants.WMQ_MQMD_READ_ENABLED, true);

  ((JmsDestination) responseQ).setObjectProperty( WMQConstants.JMS_IBM_MQMD_CORRELID, msgIdText);

  jmsTemplate.setReceiveTimeout(30000L);

  String filter = "JMSCorrelationID='" + messageId + "'"; // to match request message's messageId with response message's correlationId

  TextMessage respMsg = (TextMessage) jmsTemplate.receiveSelected(responseQ, filter);

下面是我的connectionFactory代码:

 MQConnectionFactory factory = new MQQueueConnectionFactory();
 factory.setHostName("hostname");
 factory.setPort(1420);
 factory.setQueueManager("QM1");
 factory.setChannel("TEST.CHANNEL");
 factory.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT);

此处的主要问题是尚未执行基本诊断,或者如果尚未执行基本诊断,则结果不会出现在问题中。 我不了解Spring,但我知道基本的MQ调试。 我还住在密苏里州,即“ Show Me”州,足够长的时间接受该州的座右铭。 向我展示如何验证所有假设。 作为MQ管理员,我将与开发人员一起通过目视检查确认所有假设。 这是我的处理方法:

检查出站邮件

  1. 停止出站频道
  2. 放置请求消息
  3. GET(ENABLE)XMitQ并浏览消息
    a)消息出现了吗?
    b)消息是否具有正确的格式和值?
    c)是否正确填写了“回复”字段?
    d)消息是否到期,如果到期,消息是否足够长?

检查退货消息

  1. 停止申请
  2. 重新启动出站频道
  3. 浏览回复队列
    a)消息到达了吗?
    b)是否正确格式化和填充?

摘要
最后,只有两种可能的情况可能会出错,并且都易于检查。

首先,新程序可能根本没有发出任何消息。 在重构代码以使用新框架时,这实际上很常见。 尝试在不积极验证消息的情况下进行调试会导致PUT(并明确说明问题的完成方式和结果),这是一个非常大的假设。 不要假设 验证是否产生了一条消息,并在询问时将详细信息告诉我们,以便从根本上消除该消息。

其次,从接收请求的应用程序向后工作,它不在乎哪个应用程序发送消息是否相同。 假设请求者应用程序实际上是在发送消息,则它与旧消息应用程序可能不一样,因为它从远程服务器应用程序获得了不同的响应。 比较旧版和新版应用中同一交易的消息。 将它们打印为十六进制,并在必要时逐字节比较字节。

在执行了这种鉴别诊断之后,有可能缩小关注范围并找到根本原因。 检查是否没有消息产生的事物列表与检查消息是否真正产生的条目列表有很大的不同。 无需进行基本诊断即可解决此问题,但这是例外。 因此,我的无答案的答案是:首先进行基本诊断。

您正在将消息ID从字节转换为字符串,然后在过滤器字符串中使用它。 我更喜欢使用以下内容,因为MQ JMS已经已经完成了从字节到字符串的转换。

String filter = "JMSCorrelationID='" + txtMsg.getJMSMessageID()  + "'";

您必须使用ID:前缀,另请参阅此IBM Technote

// Create IBM MQ specific correlation ID
public static String jmsCorrelId(String correlId) {
    return "ID:" + javax.xml.bind.DatatypeConverter.printHexBinary(correlId.getBytes()).toLowerCase();
}

// Create IBM MQ specific JMS selector to receive message by correlation ID
public static String jmsCorrelIdSelector(String correlId) {
    return "JMSCorrelationID='" + jmsCorrelId(correlId) + "'";
}

在代码中使用上述辅助函数,如下所示:

String correlId = "MyCorrelId";
txtMsg.setJMSCorrelationID(correlId);
...
String filter = jmsCorrelIdSelector(correlId);
TextMessage respMsg = (TextMessage) jmsTemplate.receiveSelected(responseQ, filter);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM