【问题标题】:MQQueue get call fails to get the message from queueMQQueue get 调用无法从队列中获取消息
【发布时间】:2018-08-04 05:53:46
【问题描述】:

MQQueue get 调用无法从队列中检索消息,出现 2033 (07F1) (RC2033):MQRC_NO_MSG_AVAILABLE 错误。我正在使用以下代码从队列中获取消息:

获取消息:

    byte[] replyMessageBytes = null;
    try {
        this.replyConnection.open();

        MQQueue replyQueue = this.replyConnection.getQueue(CMQC.MQOO_INPUT_AS_Q_DEF);
        if (null == replyQueue) {
            logger.error("Could not create reply queue.");
            throw new PFMCommunicationException("Could not create reply queue.");
        }

        MQMessage replyMessage = new MQMessage();
        MQGetMessageOptions gmo = new MQGetMessageOptions();
        gmo.resolvedQueueName = replyQueue.getResolvedQName();
        if (timeout.length > 0) {
            try {
                gmo.waitInterval = Integer.valueOf("" + timeout[0]);
            } catch (NumberFormatException e) {
            }
        } else {
            gmo.waitInterval = MQConstants.MQWI_UNLIMITED;
        }
        gmo.options = MQConstants.MQGMO_WAIT;
        if (null != correlationId) {
            gmo.matchOptions = MQConstants.MQMO_MATCH_MSG_ID | MQConstants.MQMO_MATCH_CORREL_ID;
            replyMessage.messageId = correlationId.getBytes();
            replyMessage.correlationId = correlationId.getBytes();
        } else {
            gmo.matchOptions = MQConstants.MQMO_NONE;
            replyMessage.messageId = MQConstants.MQMI_NONE;
            replyMessage.correlationId = MQConstants.MQCI_NONE;
        }

        try {
            replyQueue.get(replyMessage, gmo);
            int length = replyMessage.getMessageLength();
            replyMessageBytes = replyMessage.readStringOfByteLength(length).getBytes();
        } catch (MQException e) {
            logger.error("ERROR on receiving reply: CC=" + e.completionCode + " RC=" + e.reasonCode + " "
                    + e.getMessage());
        } catch (IOException e) {
            logger.error("ERROR on receiving reply.", e);
        }

        if (null == replyMessageBytes) {
            logger.error("No reply received.");
        } else {
            logger.debug("Received message: " + new String(replyMessageBytes));
        }
    } catch (MQException e) {
        logger.error("ERROR:", e);
        throw new PFMCommunicationException(e);
    } catch (PFMConnectionException e) {
        logger.error(e.getMessage());
        throw new PFMCommunicationException(e);
    } finally {
        this.replyConnection.close();
        logger.debug("Closed connection with MQ replies.");
    }

我确认消息在 waitInterval 到期之前存在于队列中,并且correlationId 也匹配。事实上,当我运行代码而不尝试匹配correlationId 时,我能够得到消息。我想这意味着响应消息有问题,或者我在正确创建 matchOptions 时出错。

    gmo.matchOptions = MQConstants.MQMO_NONE;
    replyMessage.messageId = MQConstants.MQMI_NONE;
    replyMessage.correlationId = MQConstants.MQCI_NONE;

这是我的响应消息头的样子:

   <Header Origin="DISPUTE1" Addressee="PSXDX2" Date="20180802" Time="123055" Area="QUERY" Content="RAddr" ID="8af3257cf01a4842bf5eec8d" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="cms/customerAccountDetails.xsd">

我尝试在响应标头中放置 CorrelId 而不是 ID,但它仍然相同。有人可以帮我找出问题吗?

【问题讨论】:

  • 您的意思是要请求消息 id 与相关 id 值相同的消息吗?
  • @MoragHughson 我想要的是获取与messageId 或correlationId 匹配的消息。我在 Roger 的回答中添加了一条评论,以提供我如何测试功能的场景。
  • 通常你会得到一个或另一个,而不是两者兼而有之。正常情况是回复将在相关 ID 中填充原始请求 msgid。回复消息 msgid 将是新的且唯一的,与请求消息无关。

标签: ibm-mq


【解决方案1】:
if (null != correlationId) {
  gmo.matchOptions = MQConstants.MQMO_MATCH_MSG_ID | MQConstants.MQMO_MATCH_CORREL_ID;
  replyMessage.messageId = correlationId.getBytes();
  replyMessage.correlationId = correlationId.getBytes();
}

好吧,那是你的问题。 MQ 消息在 MsgId 和 CorrelId 字段中具有相同值的情况非常罕见。

如果您收到针对您发送的请求的回复消息,并且您在 MQPUT 之后保存了 请求消息的 MsgId,则代码应为:

if (null != correlationId) {
  gmo.matchOptions = MQConstants.MQMO_MATCH_CORREL_ID;
  replyMessage.correlationId = correlationId.getBytes();
}

注意:您不保存请求(出站)消息的 CorrelId,而是保存 MsgId。处理您的请求的服务器应该将传入的 MsgId 放在回复消息的 CorrelId 中。因此,这就是为什么您只在 CorrelId 上匹配回复消息。

【讨论】:

  • 我试过你的建议,但还是一样。让我给你一个我如何测试功能的场景。回复消息来自第三方。由于我没有任何虚拟实现,因此我执行以下操作:我在调试模式下运行应用程序。执行 put message 部分,通过复制 header 的 ID 属性中的 correlationId 来准备回复消息,将其手动放入回复队列并运行 get message 部分。我想我是如何传递信息的是错误的。手动放的时候,MsgId或者CorrelId怎么放回复消息里?
  • 您的代码在哪里显示将消息放入队列,然后将 MsgId 保存为字节数组,即 byte[]
  • 我发现了问题。我们有一个拦截器,它拦截来自队列的传入消息并将消息转发到应用程序连接到的队列中。我们需要这个,因为并非所有的信息都是为​​我们准备的。所以拦截器确保我们只读取那些给我们的消息,并将 ID 值放入相关 ID。有一项检查失败,因此相关 ID 被替换为空字符串。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-10
  • 1970-01-01
  • 1970-01-01
  • 2015-11-22
  • 1970-01-01
相关资源
最近更新 更多