我创建了一个使用JMS将消息发送到MQ队列的Java应用程序。我使用setJMSMessageId()和setJMSCorrelationId()设置消息id和相关id。发送结束时,messageId似乎被覆盖。我用Google搜索了一下,看起来即使发送它也会覆盖messageId。
此应用程序的要求是messageId和correlationId在发送和接收时都具有相同的值。我有什么可以做的吗?
注意:我正在使用JDK 1.6和WAS 8.5来部署应用程序。此WAS与MQ队列管理器通信。
答案 0 :(得分:6)
消息ID是为消息系统设置的。你可以阅读它,例如记录甚至保留它,但没有别的。 Esp。,它不应该由应用程序设置!只有在两个消息传递系统之间进行桥接时,setter才会存在,即当您从一个消息传递系统X收到消息并将其转发到另一个消息传递系统Y时。然后Y需要能够设置该消息对象的消息ID,甚至虽然Y没有创建它,即使它不是Y自己的实现。这个用例有几种方法,它引起了很多混乱;最好忽略它们。
OTOH,关联ID是供您的应用程序使用的。一种非常常见的模式是request-response对消息,这是混淆的第二个来源:
send
方法之一时,消息ID由消息传递系统设置,A存储此消息ID。还有很多其他的消息交换模式,例如一个请求多个回复或未经请求的消息,并且正确使用相关性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可以包含以下其中之一:
- 特定于提供者的消息ID
- 特定于应用程序的字符串
- 提供者本地字节[]值
在某些情况下,一个应用程序(由多个客户端组成)需要 使用特定于应用程序的值链接消息。例如, 应用程序可以使用JMSCorrelationID来保存值引用 一些外部信息。应用程序指定的值不得启动 加上“ ID:”前缀;这保留给提供商生成的消息 ID值。