【问题标题】:How to set JMSMessageID and JMSCorrelationID properly?如何正确设置 JMSMessageID 和 JMSCorrelationID?
【发布时间】:2014-06-11 12:34:18
【问题描述】:

我制作了一个使用 JMS 将消息发送到 MQ 队列的 Java 应用程序。我使用 setJMSMessageId() 和 setJMSCorrelationId() 设置消息 ID 和相关 ID。 messageId 似乎在发送结束时被覆盖。我google了一下,似乎服务器会覆盖messageId,即使你发送它。

此应用的要求是messageId 和correlationId 在发送和接收时具有相同的值。对此我无能为力吗?

注意:我使用 JDK 1.6 和 WAS 8.5 来部署应用程序。此 WAS 与 MQ 队列管理器进行通信。

【问题讨论】:

    标签: java jms ibm-mq


    【解决方案1】:

    消息 ID 保留给消息传递系统设置。你可以阅读它,例如,记录甚至持久化它,但除此之外别无他法。特别是,它不应该由应用程序设置!设置器仅在两个消息传递系统之间进行桥接时存在,即当您从一个消息传递系统 X 接收消息并将其转发到不同的消息传递系统 Y 时。然后 Y 需要能够设置该消息对象的消息 ID,即使尽管 Y 没有创建它,即即使它不是 Y 自己的实现。这个用例有几种方法,它引起了很多混乱;最好忽略它们。

    OTOH,相关 ID 供您的应用程序使用。一个非常常见的模式是request-response 一对消息,这是第二个混淆来源:

    1. 原始发件人 A 向目标 D 发送消息,其中回复标题字段设置为 A 期望接收回复的目标 D'。当 A 调用各种 send 方法之一时,消息 id 由消息传递系统设置,并且 A 存储此消息 id。
    2. 然后B收到消息,处理业务逻辑,回复D'。它还将相关 id 设置为它刚刚收到的消息的消息 id。回复消息还会从消息传递系统中获得一个新的消息 ID,但这与此模式无关。
    3. 最后 A 收到 D' 的回复消息,读取关联 id,并使用它来查找它在步骤 1 中存储的消息 id。

    还有很多其他的消息交换模式,比如一请求多回复或主动消息,正确使用相关 ID 是必不可少的;但是请求-回复是迄今为止最常见的。这就是为什么它甚至在 JavaDoc 中被建议。否则消息 ID 与相关 ID 无关。这让初学者感到困惑。我什至发现将消息与业务密钥相关联而不是消息 ID 更可取。

    回到您的问题:由于您在发送消息之前设置了相关 ID,并且消息 ID 是在您发送消息时由消息传递系统设置的,因此 JMS-API 无法同时设置这两个值相同的值。

    【讨论】:

    • 好的,明白了。那么假设我将消息从DataQueue传输到MQ,有没有办法在JMS-API设置消息ID之后,我可以将关联ID设置为与消息ID相同的值?跨度>
    • 消息 id 在 send 方法中设置,在消息返回后,消息可能已经以某种方式持久化,即即使您更改消息对象,实际发送的消息可能或可能没有您设置的相关 ID。可能值得一试,但绝对不便携。
    【解决方案2】:
    I set it in the application because MQ needs it
    

    IBM MQ 不需要设置 MessageID,MQ 会自行生成唯一的 MessageID。回复时,响应应用程序应使用传入(也称为请求)消息的 MessageID(由 IBM MQ 设置)并将其设置为回复消息上的 CorrelationID。这样,请求者应用程序将能够关联请求和回复。

    【讨论】:

      【解决方案3】:

      我使用 setJMSMessageId() 和 setJMSCorrelationId().

      告诉您这样做的人不了解正确的消息传递设计,也不应该设计中间件基础架构。消息 ID 在 MQ 环境中应该是唯一的。如果您需要在 2 个消息传递应用程序之间共享令牌/数据值,请使用关联 ID。

      【讨论】:

      • 好的,对于初学者来说,它是在来自另一个队列(没有消息或相关 ID)时设置的,我在应用程序中设置它是因为 MQ 需要它,想法是它在回复时返回相同的消息和相关 ID(我发送 1 和 2,所以回复也应该是 1 和 2)。我没有看到矛盾,我的意思是,整个想法是在整个交流过程中两者都保持独特。仅供参考,消息来自 AS400 中的数据队列。这就是没有 messageid 或相关 id 的原因。
      【解决方案4】:

      分享我 4 年后使用双胞胎 ID 的经验 -

      JMSMessageID 是由 JMS 提供程序设置的标头属性。当消息被发送到队列时,它发生在运行时。

      JMSCorrelationID 是一个标头属性,用户可以设置该属性以关联不同 JMS 提供者之间的相同消息。 引用Oracle Documentation -

      JMSCorrelationID 可以包含以下内容之一:

      1. 提供者特定的消息 ID
      2. 特定于应用程序的字符串
      3. 提供者原生字节[]值

      在某些情况下,一个应用程序(由多个客户端组成)需要 使用特定于应用程序的值来链接消息。例如, 应用程序可以使用 JMSCorrelationID 来保存值引用 一些外部信息。应用程序指定的值不得启动 带有“ID:”前缀;这是为提供者生成的消息保留的 ID 值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-02-04
        • 2023-03-24
        • 1970-01-01
        • 2016-07-07
        • 2017-03-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多