【问题标题】:No response when using IBM MQ client jars in application to connect to IBM MQ server在应用程序中使用 IBM MQ 客户端 jar 连接到 IBM MQ 服务器时没有响应
【发布时间】:2017-05-19 14:37:26
【问题描述】:

我正在处理的应用程序需要与远程位置的 IBM MQ 服务器通信。我们目前有一个使用活动 MQ 的工作系统,该系统使用代理和一个桥来连接到这个远程 IBM MQ 服务器并且工作正常。

由于一些新的增强功能,我们现在尝试使用 IBM 客户端 jars 而不是 Active MQ 来实现相同的功能。

我面临的问题是我可以连接到远程服务器的 inboundQ 并发送消息。但是我总是从远程服务器的出站队列接收 null。但是我无法检查是否在远程位置收到了消息。但是如果通过旧的 ActiveMQ 系统发送相同的消息,则会得到远程 MQ 服务器的响应。

旧的 Active MQ 在内部使用网桥连接到远程 IBM MQ 服务器,该服务器的配置与我使用的新代码完全相同。

我尝试了来自互联网的多个代码和堆栈溢出本身,我总是能够连接但没有得到任何响应。

此外,在尝试从远程 IBM MQ 发送或接收数据时,我没有收到任何错误或异常。

我将粘贴我正在尝试开始工作的示例代码。我已经更改了代码中的一些配置值。

我的疑惑如下。

  1. 为此,我所做的只是将 IBM MQ 客户端 jar 复制到应用程序中,并使用代码将消息发送到远程 MQ。我没有安装任何其他应用程序。这样的系统会工作吗?还是应该有一些中间程序,比如活动 MQ?

  2. 相同的代码能够从我安装在本地网络中的 IBM MQ 服务器发送和接收,但无法从远程服务器获得响应?这让我相信如果我在配置中遗漏了什么?除了在代码中还应该配置什么?

  3. 我没有看到任何错误或异常。始终发送消息,但响应为空。我还没有看到使用任何用户名-密码或公钥-私钥身份验证。是否有任何通常用于检查来源的身份验证。 ?

  4. 我正在使用我知道旧的 IBM MQ 客户端 5.3 版本。但是使用它,因为他们工作的活动 MQ 设置使用相同并且工作正常。我无法知道远程机器上存在 IBM MQ 服务器上的哪个版本。如果我们使用与服务器 MQ 版本不同的客户端 MQ 版本,是否会出现问题。 ?

在本地环境中适用于我的示例代码,即能够从我安装在本地网络中另一台机器上的 IBM MQ 服务器发送和接收。当我尝试将它与远程 IBM MQ 服务器一起使用时,相同的代码将获取空响应。

import javax.jms.*;
import javax.jms.JMSException;
import com.ibm.mq.jms.*;
import com.ibm.jms.JMSMessage;
import javax.jms.TextMessage;

public class SendReceive {
    private MQQueueConnectionFactory connectionFactory;
    private MQQueueConnection connection;

    private void runTest() {
        try {
            connect();
            connection.start();
            MQQueueSession session = (MQQueueSession) connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
            MQQueue queue = (MQQueue) session.createQueue("INBOUND_QUEUE");     /* values  replaced with correct values in deployment server */
            MQQueue queue2 = (MQQueue) session.createQueue("OUTBOUND_QUEUE");   /* values  replaced with correct values in deployment server */
            MQQueueSender sender = (MQQueueSender) session.createSender(queue);     

            MQQueueReceiver receiver = (MQQueueReceiver) session.createReceiver(queue2);

            //TextMessage message = session.createTextMessage("yesyesyes");
            String stt = "Test Message";        //

            TextMessage message = session.createTextMessage(stt);
            message.setJMSReplyTo(queue2);
            sender.send(message);
            System.out.println("Sent: " + message);

            Message msg1 = receiver.receive(5000);
            if(msg1!=null){
                String responseMsg = ((TextMessage) msg1).getText();
                System.out.println("Received: " + responseMsg);
            }else{
                System.out.println("Message received is null");
            }
        }catch(Exception e){
            System.out.println("Exception caught in program : " + e);
            e.printStackTrace();
        }
    }

    public boolean connect() {
        boolean connected = false;
        try {
            /* values below are replaced with correct values in deployment server */

            connectionFactory = new MQQueueConnectionFactory();            
            connectionFactory.setPort(1515);
            connectionFactory.setHostName("192.168.1.23"); // 
            connectionFactory.setQueueManager("QCCMGR");
            connectionFactory.setChannel("QCHANNEL");            
            connectionFactory.setTransportType(JMSC.MQJMS_TP_CLIENT_MQ_TCPIP);

            connection = (MQQueueConnection) connectionFactory.createQueueConnection();
            connected = true;
        } catch (Exception e) {
            connected = false;
        }
        return connected;
    }

    public static void main(String[] args) {
        new SendReceive().runTest();
    }

}

【问题讨论】:

  • @JoshMc 示例程序在同一台机器上以相同的用户和相似的配置运行。当我尝试连接发送或接收时,它永远不会出现错误或异常。我发送消息的远程系统不属于我工作的公司,所以我无法检查他们是否收到。但是远程服务器响应从使用 MQ5.3 jar 的 activeMQ 桥发送的消息。我使用 5.3 的原因只是因为旧的工作系统使用的是相同的。我打算尝试更新版本,但不知何故我觉得我在这里缺少一些步骤或配置
  • @JoshMc 旧的 activeMQ 网桥设置也使用两个程序,一个发送,一个接收。如果我使用旧的活动 MQ 网桥设置发送,我确信消息会到达远程。我尝试使用旧系统发送,然后尝试使用我的示例程序获取响应。然后我也收到空值或空值作为响应。但是如果我运行旧的 pgm 之后接收,我将得到对发送的消息的响应,这意味着消息存在于远程队列中,但由于某种原因没有发送到我的样品 pgm。为什么会发生这种情况我无法理解。
  • @JoshMc 旧系统使用 5 秒。我已经尝试了 10、15、30 秒,但仍然只收到 null 作为响应,所以我认为超时不是问题。我尝试评论发送部分的代码并仅运行接收部分程序,但连接时再次没有错误,但响应为空。
  • 如果您使用新系统发送消息,那么您可以使用旧系统检索该消息吗?
  • @RobParker 否 如果我使用新系统发送,我不会收到使用旧系统的响应。

标签: java jms activemq message-queue ibm-mq


【解决方案1】:

MQ v5.3 于 2002 年 11 月 29 日发布,自 2007 年 9 月 28 日(将近 9 年)起已停止支持。该版本可能与您的问题无关,但我强烈建议您迁移到受支持的 MQ 客户端版本。较新的 MQ 客户端版本可以连接到较旧的 MQ 队列管理器。您可以通过以下链接下载仅 Java 安装的 MQ 8.0 或 MQ 9.0 jar 文件:


我在一些旧线程上读到,当指定超时时,发送者和接收者在同一个会话中会导致问题。尝试为接收者添加另一个会话。

    private void runTest() {
        try {
            connect();
            connection.start();
            MQQueueSession session = (MQQueueSession) connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
            MQQueueSession session2 = (MQQueueSession) connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
            MQQueue queue = (MQQueue) session.createQueue("INBOUND_QUEUE");     /* values  replaced with correct values in deployment server */
            MQQueue queue2 = (MQQueue) session2.createQueue("OUTBOUND_QUEUE");  /* values  replaced with correct values in deployment server */
            MQQueueSender sender = (MQQueueSender) session.createSender(queue);     

            MQQueueReceiver receiver = (MQQueueReceiver) session2.createReceiver(queue2);

            //TextMessage message = session.createTextMessage("yesyesyes");
            String stt = "Test Message";        //

            TextMessage message = session.createTextMessage(stt);
            message.setJMSReplyTo(queue2);
            sender.send(message);
            System.out.println("Sent: " + message);

            Message msg1 = receiver.receive(5000);
            if(msg1!=null){
                String responseMsg = ((TextMessage) msg1).getText();
                System.out.println("Received: " + responseMsg);
            }else{
                System.out.println("Message received is null");
            }
        }catch(Exception e){
            System.out.println("Exception caught in program : " + e);
            e.printStackTrace();
        }
    }

尝试通过将以下内容添加到 java 应用程序的执行来获取 JMS 跟踪:

-DMQJMS_TRACE_LEVEL=base
-DMQJMS_TRACE_DIR=/tracedirectory

例如:java -DMQJMS_TRACE_LEVEL=base -DMQJMS_TRACE_DIR=/tracedirectory JavaApp

这应该会在您指定的目录中生成一个我认为以 .trc 结尾的文件。

您可以查看此内容是否有错误,这些错误可能有助于为您指明正确的方向。


建议:

尝试更改您的程序以强制它发送空白用户名:

connection = (MQQueueConnection) connectionFactory.createQueueConnection("", "");

在调用sender.send 后尝试关闭发件人

sender.close(); 

如果没有进一步的信息,很难确定原因。收集的信息越多越好。

【讨论】:

  • 我已经尝试过仅接收程序,其中会话仅用于接收,所以不要认为这是一个问题。但一定会试一试。
  • 我现在只能在一周左右之后才能访问部署系统,因为那里正在进行一些其他工作。到时候我会设法找到踪迹。我确信没有其他应用程序连接接收响应。如果我使用旧系统发送并尝试使用新系统接收,则没有响应,但之后如果我尝试旧系统接收,我会得到响应。所以远程队列有响应但没有发送到新系统或由于某种原因在传输过程中丢失。
  • @Raj 我认为这两件事很好地表明发送或接收都不起作用。 1.从旧系统发送,并尝试从新系统接收,没有响应,启动旧系统接收器并且消息存在。 2.从新系统发送,旧系统接收器没有收到任何东西。
  • 我同意发送或接收都不起作用。但这是让我失败的原因。所有连接参数均正确无误,无异常。旧系统和新系统也发送相同的消息。如果我 gv 错误的连接参数,例如错误的入站/出站队列名称,则会引发异常,这意味着连接成功。为什么没有传递消息让我失望。我也确认没有用户名/密码等用于连接。验证似乎是消息本身的一部分,通过旧系统或新系统发送时是相同的。
  • 发送接收也在开发环境中工作,当我发送到 IBM MQ 服务器时,我安装在本地网络的另一个系统中。此问题出现在旧系统工作的部署服务器中。旧系统也可以在我设置的开发环境中运行。在这一点上我没有想法,但是当我可以访问部署服务器时,我会尝试跟踪。
【解决方案2】:

这可能是一些与网络相关的配置问题,或者可能是 Windows 消息配置不正确。您可以考虑由 IBM 提供WebSphere MQ - Message Test Utility 以确保不存在此类系统或网络配置问题。

【讨论】:

    猜你喜欢
    • 2022-11-08
    • 2013-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-21
    • 1970-01-01
    • 2011-07-22
    相关资源
    最近更新 更多