在应用程序中使用 IBM MQ 客户机 jar 连接到 IBM MQ 服务器时无响应

2022-09-04 23:24:04

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

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

我面临的问题是我可以连接到远程服务器的入站Q并发送消息。但我总是从远程服务器出站队列收到空值。但是我无法检查消息是否在远程位置收到。但是,如果通过旧的 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 服务器一起使用时,相同的代码将获取 null 响应。

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

}

答案 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(); 

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


答案 2

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


推荐