如何正确设置JMSMessageID和JMSCorrelationID?

时间:2014-04-25 17:06:45

标签: java jms ibm-mq

我创建了一个使用JMS将消息发送到MQ队列的Java应用程序。我使用setJMSMessageId()和setJMSCorrelationId()设置消息id和相关id。发送结束时,messageId似乎被覆盖。我用Google搜索了一下,看起来即使发送它也会覆盖messageId。

此应用程序的要求是messageId和correlationId在发送和接收时都具有相同的值。我有什么可以做的吗?

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

4 个答案:

答案 0 :(得分:6)

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

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

  1. 原始发件人A向目的地D发送消息,其中回复标题字段设置为目的地D',其中A期望接收回复。当A调用各种send方法之一时,消息ID由消息传递系统设置,A存储此消息ID。
  2. 然后B接收消息,处理业务逻辑,并回复D'。它还将相关ID设置为刚收到的消息的消息ID。回复消息还从消息传递系统获取新的消息ID,但这与此模式无关。
  3. 最后A收到来自D'的回复消息,读取相关ID,并使用它来查找它在步骤1中存储的消息ID。
  4. 还有很多其他的消息交换模式,例如一个请求多个回复或未经请求的消息,并且正确使用相关性ID是必不可少的;但请求 - 回复是目前最常见的。这就是为什么它甚至在JavaDoc中提出。否则消息ID与关联ID 无关。这对初学者来说很困惑。我甚至发现最好将消息与业务密钥相关联,而不是消息ID。

    回到您的问题:在发送消息之前设置相关ID,并且在发送消息时消息系统设置了消息ID,JMS-API中无法同时生成这两个值相同的价值。

答案 1 :(得分:3)

I set it in the application because MQ needs it

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

答案 2 :(得分:2)

  

我使用setJMSMessageId()和set设置了消息id和相关id   setJMSCorrelationId()。

无论谁告诉你这样做,都不了解正确的消息传递设计,也不应该设计中间件基础设施。消息ID在MQ环境中应该是唯一的。如果需要在两个消息传递应用程序之间共享令牌/数据值,请使用相关ID。

答案 3 :(得分:0)

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

JMSMessageID是由JMS Provider设置的标头属性。将消息发送到队列时,它会在运行时发生。

但是JMSCorrelationID是标头属性,用户可以设置其属性以在不同JMS提供程序之间关联同一消息。 引用Oracle Documentation-

  

JMSCorrelationID可以包含以下其中之一:

     
      
  1. 特定于提供者的消息ID
  2.   
  3. 特定于应用程序的字符串
  4.   
  5. 提供者本地字节[]值
  6.   
     

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