Java 如何正确设置 JMSMessageID 和 JMSCorrelationID?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23299147/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 21:44:44  来源:igfitidea点击:

How to set JMSMessageID and JMSCorrelationID properly?

javajmsibm-mq

提问by Xanathos

I made a java app that uses JMS to send messages to an MQ Queue. I set the message id and correlation id with the setJMSMessageId() and setJMSCorrelationId(). The messageId seems to be overwritten when the sending ends. I googled a bit, and seems that the server overwrites the messageId even when you send it.

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

The requirement for this app is that both messageId and correlationId have the same value when sent and when received. Isn't there anything I can do about this?

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

Note: I am using JDK 1.6, and a WAS 8.5 to deploy the app. This WAS communicates with a MQ Queue Manager.

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

回答by Roger

I set the message id and correlation id with the setJMSMessageId() and setJMSCorrelationId().

我使用 setJMSMessageId() 和 setJMSCorrelationId() 设置了消息 ID 和关联 ID。

Whoever told you to do this, does not understand proper messaging design and should not be designing middleware infrastructure. A message id should be unique in an MQ environment. If you need to share a token/data value between 2 messaging applications then use the correlation id.

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

回答by Shashi

I set it in the application because MQ needs it

IBM MQ does not require a MessageID to be set, MQ will generate a unique MessageID on it's own. When replying, the responding application should use the MessageID (set by IBM MQ)of the incoming (aka request) message and set it as CorrelationID on the reply message. This way the requester application will be able to relate request & reply.

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

回答by rü-

Message ids are reserved for the messaging system to set. You can read it and, e.g., log or even persist it, but nothing else. Esp., it's not supposed to be set by an application! The setter is there only when bridging between two messaging systems, i.e. when you receive a message from one messaging system X and forward it to a different messaging system Y. Then Y needs to be able to set the message id of that message object, even though Y has not created it, i.e. even though it's not Y's own implementation. There are several methods for this use case and it's causing a lot of confusion; it's best to just ignore them.

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

OTOH, correlation ids are for your application to use. A very common pattern is a request-responsepair of messages, and this is the second source of confusion:

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

  1. An original sender A sends a message to a destination D with the reply-to header field set to a destination D' where A expects to receive the replies. The message id is set by the messaging system when A calls one of the various sendmethods, and A stores this message id.
  2. Then B receives the message, handles the business logic, and replies to D'. It also sets the correlation id to the message id of the message it just received. The reply message also gets a new message id from the messaging system, but that is irrelevant for this pattern.
  3. Finally A receives the reply message from D', reads the correlation id, and uses that to look up the message id it has stored in step 1.
  1. 原始发件人 A 向目的地 D 发送一条消息,其中回复标头字段设置为目的地 D',A 期望在该目的地接收回复。当 A 调用各种send方法之一时,消息 id 由消息传递系统设置,并且 A 存储此消息 id。
  2. 然后B接收消息,处理业务逻辑,回复D'。它还将相关 id 设置为它刚刚收到的消息的消息 id。回复消息还从消息传递系统获取新消息 ID,但这与此模式无关。
  3. 最后 A 收到来自 D' 的回复消息,读取相关 ID,并使用它来查找它在步骤 1 中存储的消息 ID。

There are a lot of other message exchange patterns, like one-request-many-replies or unsolicited messages, and the proper use of correlation ids is essential; but request-reply is by far the most common. That's why it's even suggested in the JavaDoc. Otherwise message ids have nothing to do with correlation ids. This is confusing for beginners. I even found it preferable to correlate messages with business keys instead of message ids.

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

Coming back to your question: as you set the correlation id before you send the message, and the message id is set by the messaging system when you send the message, there is no way in the JMS-API to make both values the same value.

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

回答by pro_cheats

Sharing my experience with the twin IDs after 4 years -

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

JMSMessageIDis a header property set by the JMS Provider. It happens at runtime when the message is being sent to the Queue.

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

But JMSCorrelationIDis a header property that can be set by the users to correlate the same message across different JMS Providers. Quoting from Oracle Documentation-

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

A JMSCorrelationID can hold one of the following:

  1. A provider-specific message ID
  2. An application-specific String
  3. A provider-native byte[] value

In some cases, an application (made up of several clients) needs to use an application-specific value for linking messages. For instance, an application may use JMSCorrelationID to hold a value referencing some external information. Application-specified values must not Start with the 'ID:' prefix; this is reserved for provider-generated message ID values.

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

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

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