【问题标题】:Is it possible to use built-in correlation when publishing message to MQ Topic?将消息发布到 MQ 主题时是否可以使用内置关联?
【发布时间】:2011-11-10 15:44:44
【问题描述】:

我只是有点迷失在 WebSphere MQ 7 中使用主题。假设一个简单的场景:

  • 我有一个向主题发布消息的进程。
  • 我有零个或多个订阅者接收消息。
  • 任何订阅者都可以决定对收到的消息做出反应 = 可选的“回复”。 (旁注:最初的决定也是使用主题进行回复,但如有必要我会将其更改为队列)发布的消息可以配置ReplyToQueueName,也可以是客户端上的系统级配置。
  • 响应必须与原始发布的“请求”相关联(因为发布的请求可能不止一个)。

现在该怎么做?我尝试使用发起者选择的 MQ 队列中的常用方法:

  • 将报告设置为MQRO_COPY_MSG_ID_TO_CORREL_ID。接收方将从请求中获取消息 ID,并将其作为关联 ID 作为响应传递。
  • 将报告设置为MQRO_PASS_CORREL_ID + 在请求消息中设置相关 ID。接收方将从请求中获取关联 ID,并将其设置为响应消息中的关联 ID。

在这两种情况下,发送者都知道传递给请求的消息 ID 或相关 ID,因此它可以正确关联消息,但这不适用于 MQ 主题。

如果我尝试遵循上述方法,我会在发布请求时立即遇到问题 - 消息 ID 未在发布者端设置(它为空),因此第一种方法是不可能的。如果我尝试在发布者端设置相关 ID,我将在订阅者端获得不同的 ID,因此我不能将其用于消息相关(= 第二种方法也不可能)。

以下是使用主题时发生的一些示例(ID 采用 Base64 格式):

使用MQRO_COPY_MSG_ID_TO_CORREL_ID进行测试:

Send request: // After sending message publisher doesn't know its ID!
Message Id:     AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Correlation Id: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

Received request: // Subscriber gets some ID and correlation ID (but publisher didn't set any)
Message Id:     QU1RIExNLnF1ZXVlLm1hbp2OiU4g6AYH
Correlation Id: QU1RIExNLnF1ZXVlLm1hbp2OiU4g6AYF

Send response:  // Subscriber correctly uses message ID of incoming request
Message Id:     AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Correlation Id: QU1RIExNLnF1ZXVlLm1hbp2OiU4g6AYH

Received response: // Publisher gets in response completely different IDs!
Message Id:     QU1RIExNLnF1ZXVlLm1hbp2OiU4g6AYP
Correlation Id: QU1RIExNLnF1ZXVlLm1hbp2OiU4g6AYN

使用MQRO_PASS_CORREL_ID进行测试:

Send request: // Publisher doesn't know its ID but it generated some random correlation ID.
Message Id:     AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Correlation Id: Chhv8KT+zhTjfAEdzeiB3cizw9vRy9Pf

Received request: // Subscriber got ANOTHER correlation ID!
Message Id:     QU1RIExNLnF1ZXVlLm1hbp2OiU4g6AYY
Correlation Id: QU1RIExNLnF1ZXVlLm1hbp2OiU4g6AYW

Send response:  // Subscriber is using incorrect correlation ID.
Message Id:     AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Correlation Id: QU1RIExNLnF1ZXVlLm1hbp2OiU4g6AYW

Received response: // Publisher gets in response completely different IDs!
Message Id:     QU1RIExNLnF1ZXVlLm1hbp2OiU4g6AYg
Correlation Id: QU1RIExNLnF1ZXVlLm1hbp2OiU4g6AYe

如何强制 MQ 不更改我的 ID?我用 Java 和 .NET 编写了测试应用程序,它们的行为方式相同。或者我的用例的正确方法是什么?

【问题讨论】:

    标签: java .net publish-subscribe ibm-mq


    【解决方案1】:

    您是否考虑过使用 JMS(MQ 作为实现)而不是直接使用 MQ api 对其进行编码?

    JMS 在发布的消息中已经有了replyTo 的概念,并且已经有了将消息链接在一起的correlation id 的概念。对于replyTo,发布者可以指定队列或主题,因此您在接收端不受任何约束。

    【讨论】:

    • 我们已经有了 JMS over MQ 实现。它有类似的问题,但我们至少能够使用第二种方法。现在我们需要支持原生 MQ ...
    【解决方案2】:

    消息 ID 在消息系统中是唯一的。在发布/订阅模式下,消息传递引擎将发布者发送的消息副本发布给多个(未知)订阅者。每个副本消息都会有不同的消息 ID,因为消息 ID 必须是唯一的。

    编辑:

    再次阅读信息中心,这是我发现的。

    您可以使用MQSO_SET_CORREL_ID 选项强制队列管理器保留应用程序设置的correlId。

    int subOptions = MQC.MQOO_FAIL_IF_QUIESCING | MQC.MQOO_INPUT_SHARED | MQC.MQSO_SET_CORREL_ID;
    MQTopic sub = qm.AccessTopic(recvQ, "/TEST/CORRELID", null, subOptions);
    

    需要注意的是,如果您在创建订阅时使用MQSO_MANAGED选项,则不能使用MQSO_SET_CORREL_ID。

    发布时将 correlID 设置为

    putMsg.CorrelationId = Encoding.ASCII.GetBytes("THISISTHECORRELID");
    topicCorrelId.Put(putMsg);
    

    接收发布时,您可以使用 match correl id 选项,如

    gmo.MatchOptions = MQC.MQMO_MATCH_CORREL_ID;
    fwdMsg.CorrelationId = Encoding.ASCII.GetBytes("THISISTHECORRELID"); 
    
    sub.Get(fwdMsg, gmo);
    

    仅当您使用队列进行多个订阅并且只想获取特定主题的发布时,才使用MQMO_MATCH_CORREL_ID。

    【讨论】:

    • 这解释了为什么第一种方法不起作用(这是我所期望的),但它没有解释为什么相关 ID 在接收方也发生了变化。您的回答意味着 MQ 在发布/订阅模式下没有对消息关联的内置支持。在这种情况下,发布/订阅应该有完全不同的 API,只有支持的功能。
    • 你能否解释一下为什么第二种机制不起作用?我知道,如果引擎发布消息的副本,它会更改消息 ID,但为什么它也会更改关联 ID(如果我使用 JMS over MQ,它不会更改 JMS 关联 ID)?
    猜你喜欢
    • 2023-02-26
    • 2023-03-16
    • 1970-01-01
    • 2016-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-25
    • 2021-04-30
    相关资源
    最近更新 更多