无法使用JMS应用程序从IBM MQ获得响应 [英] Not able to get response from IBM MQ using JMS application

查看:310
本文介绍了无法使用JMS应用程序从IBM MQ获得响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们使用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调试.我还住在密苏里州,即向我展示"州,足够长的时间接受该州的座右铭.向我展示如何验证所有假设.作为MQ管理员,我将与开发人员一起通过目视检查确认所有假设.这是我的处理方法:

检查出站邮件

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

检查退回邮件

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

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

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

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

执行这种差异诊断后,有可能缩小关注范围并找到根本原因.检查是否不产生消息的事物列表与检查是否实际产生消息的项目列表有很大的不同.可能无需进行基本诊断即可解决此问题,但这是例外.因此,我的无答案的答案是:首先进行基本诊断.

We communicate with the third party using IBM MQ in request/reply fashion. We send them request and they give us reply. Current we both have a simple java based native IBM MQ application. We are planning to rewrite our code using spring jms. But we are not getting any response back within given time when spring jms is used. We are using JMSTemplate to send or receive messages. I am sharing my code snippet. Am I doing anything wrong here? Any other properties should I set here?

  // 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);

Below is my connectionFactory code:

 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);

解决方案

The main issue here is that basic diagnostics have not been performed, or if they have then the results not presented in the question. I don't know Spring but I do know basic MQ debugging. I also lived in Missouri, the "Show Me" state, long enough to adopt the state motto as my own. Show me how all the assumptions were verified. As an MQ Admin I'd work with the developer to confirm all the assumptions by visual inspection. Here's how I'd approach it:

Inspect the outbound message

  1. Stop the outbound channel
  2. PUT a request message
  3. GET(ENABLE) the XMitQ and browse the message
    a) Does the message appear?
    b) Does the message have the right format and values?
    c) Are the Reply-To fields correctly populated?
    d) Does the message expire and if so is the expiry sufficiently long?

Inspect the return message

  1. Stop the application
  2. Restart the outbound channel
  3. Browse the reply-to queue
    a) Does a message arrive?
    b) Is it correctly formatted and populated?

Summary
In the end there are only two likely scenarios where this can go wrong and both are easy to check.

First, it is possible the new program is not putting any message at all. This is actually quite common when refactoring code to use a new framework. Trying to debug without positively verifying a message gets PUT (and explicitly stating in the question how this was done and the result) is making an awfully big assumption. Don't assume. Verify a message is produced and tell us the details when asking so we can eliminate that as a root cause.

Second, working backward from the application taking the requests, it doesn't care which app sends the message if they are the same. Assuming the requestor app is actually PUTting a message, it can't be the same as the old one since it gets a different reaction from the remote server app. Compare messages for the same transaction from the old and the new app versions. Print them out in hex and compare byte for byte if necessary.

After performing this kind of differential diagnosis it would be possible narrow the focus and get to root cause. The list of things to check if no message is produced is quite different from the list of items to check if a message is actually produced. It might be possible to resolve this without doing basic diagnostics but that would be the exception. So my non-answer answer is: start by doing the basic diagnostics.

这篇关于无法使用JMS应用程序从IBM MQ获得响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆