【问题标题】:How to get information about message retrieved from queue如何获取有关从队列中检索到的消息的信息
【发布时间】:2015-08-25 21:05:26
【问题描述】:

我是 IBM MQ 的新手。使用以下代码,我可以轻松地将消息放入队列并获取该消息。

public void QueuePut()
{
        queue = queueManager.AccessQueue("Q1", MQC.MQOO_OUTPUT + MQC.MQOO_FAIL_IF_QUIESCING);
        MQMessage message = new MQMessage();
        message.WriteString("stackoverflow");

        MQPutMessageOptions putMessageOptions = new MQPutMessageOptions(); 
        putMessageOptions.Options += MQC.MQPMO_ASYNC_RESPONSE;

        queue.Put(message, putMessageOptions);
}


public void QueueGet()
{

        queue = queueManager.AccessQueue("Q2", MQC.MQOO_INPUT_AS_Q_DEF + MQC.MQOO_FAIL_IF_QUIESCING);
        MQMessage gotMessage = new MQMessage();

        queue.Get(gotMessage);

        string str = message.ReadString(gotMessage.MessageLength);
}

您可以很容易地看到我正在向“Q1”写入消息并从“Q2”读取它,因为 Q1 是 别名队列

现在,我想要获取有关我在 QueueGet 函数中获得的消息的信息。我想知道的是 gotMessage 来自'Q1',即使我在'Q2'中阅读它。

【问题讨论】:

  • 这听起来不对,如果将 Q2 队列中的消息放在 Q1 队列中,您如何读取它?
  • @Alioza Q1 是 Q2 的别名。
  • 您还需要找出原始队列名称放在哪个位置吗?我找到了一种解决方法,通过将别名队列指向主题对象然后将目标队列订阅到主题字符串来实现这一点。这将在 MQMD 中添加可以指示原始队列名称的属性。如果您希望我写下详细信息作为答案,请告诉我?

标签: ibm-mq xms


【解决方案1】:

BaseQueueName 将指向别名队列所指的真实队列。在这种情况下,为获取队列而打开的队列就是真正的队列本身。因此BaseQueueName 不会指向任何东西。

在打开队列时使用MQC.MQCA_BASE_Q_NAME 是不对的,因为它不是队列打开选项。所有队列打开选项都以 MQOO_ 开头。

您可以使用 PCF 类来查询别名队列并找到它的基本队列名称。但目前我不知道是否有办法找到基本队列的别名。

编辑:

Alias queue 并不是像Local queue 这样的队列。顾名思义,它是本地队列的另一个名称。它不会保存任何消息。当应用程序打开别名队列时,队列管理器将其解析为实际队列。

别名有帮助

1) 隐藏它指向的队列/主题。这样,应用程序就不会受到队列/主题的任何更改的影响。

2) 为应用程序提供不同级别的权限。一个应用程序可以放入但不能获取,而另一个应用程序可以获取但不能放入同一个队列。

【讨论】:

  • 假设我们找到了一个基本队列的别名,我们怎么知道消息来自某个别名或另一个别名。即 Q1 基础 Q2 和 Q3 别名。我读了 Q1,我收到了消息,而且我知道 Q1 的别名。那么呢?我们怎么知道消息来自第二季度。如果它来自第三季度怎么办
  • 所以你的意思是我不能做我想做的事
【解决方案2】:

MQGET 返回时,MQGMO 结构有一个字段,该字段告诉您从中检索消息的本地队列的名称,即基本队列,即使您是从别名中获取的。

阅读MQGMO字段ResolvedQNamehere

以上是 C 过程 MQ API,要将其转换为您正在使用的 OO 类,这意味着您需要使用带有两个参数的 queue.Get,第二个是 MQGetMessageOptions 的实例。

"Using .NET > Handling Messages"

然后您应该能够访问MQGetMessageOptions 中的ResolvedQName 字段。

【讨论】:

  • 有消息,我把它放到'Q1',我从'Q2'读取它。在您看来,我们应该阅读 QueueGet 函数上的 MQGetMessageOptions,它给出了 Q2 的 ResolvedQName 再次是 Q2。但是,如果我们正在阅读 Q1,那么它的 ResolvedQName = 'Q2' 所以你的解决方案是正确的。即Q2为本地队列,Q1为别名队列
  • 它将始终在 ResolvedQName 字段中的别名底部为您提供本地 q。如果该队列名称与您从中获取的名称不匹配,那么您可以从中暗示一些内容。
【解决方案3】:

这是来自IBM documentation 的相关MQ 属性:

我无法对此进行测试,因为我没有测试所需的所有组件,但我相信,这应该可以:

string queueName = "Q2";
queue = queueManager.AccessQueue(queueName, MQC.MQOO_OUTPUT 
                                       + MQC.MQOO_INQUIRE
                                       + MQC.MQCA_BASE_Q_NAME
                                       + MQC.MQOO_FAIL_IF_QUIESCING);

Console.WriteLine("QueueName=" + queueName 
                  + " BaseQueueName=" + mqQueue.BaseQueueName);

if (queueName.Equals(mqQueue.BaseQueueName))
   Console.WriteLine("Message is coming from a different underlying queue");

【讨论】:

  • 在打开队列时使用 MQC.MQCA_BASE_Q_NAME 是不对的,因为它不是队列打开选项。所有队列打开选项都以 MQOO_ 开头。上面的代码不起作用。
猜你喜欢
  • 2017-04-17
  • 2011-01-13
  • 2018-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-23
  • 1970-01-01
相关资源
最近更新 更多