JMSMessageID是否应该在发布和订阅之间更改?

JMSMessageID是否应该在发布和订阅之间更改?,jms,ibm-mq,Jms,Ibm Mq,JMS 2.0规范说 JMSMessageID标题字段包含一个唯一 标识提供程序发送的每条消息 ……还有 唯一性的确切范围由提供程序定义。至少应该如此 涵盖提供程序的特定安装的所有消息,其中 安装是一组连接的消息路由器 该规范没有明确说明从发布API调用返回的JMSMessageID必须与使用时消息中存在的匹配。规范中关于在响应请求时将JMSMessageID移动到JMSCorrelationID的讨论意味着两者是相同的。如果消息ID在发布和使用之间发生更改,则此类型的请求/答复将失败 当然,在

JMS 2.0规范说

JMSMessageID
标题字段包含一个唯一 标识提供程序发送的每条消息

……还有

唯一性的确切范围由提供程序定义。至少应该如此 涵盖提供程序的特定安装的所有消息,其中 安装是一组连接的消息路由器

该规范没有明确说明从发布API调用返回的
JMSMessageID
必须与使用时消息中存在的匹配。规范中关于在响应请求时将
JMSMessageID
移动到
JMSCorrelationID
的讨论意味着两者是相同的。如果消息ID在发布和使用之间发生更改,则此类型的请求/答复将失败

当然,在JMS 1.1和现在的2.0的统一域模型中,
JMSMessageID
的行为根据目的地是队列还是主题而改变是没有意义的。在统一模式下,人们会期望所有目的地在这方面采取相同的行动

此外,如果第一段中使用的“提供者”指的是发送消息的对象,那么一个发布将扇出10条相同的消息,并且具有相同的
JMSMessageID
值,将符合规范,因为唯一性是在发送端测量的

不幸的是,该规范在使用术语“提供者”来描述发送消息的对象与使用它来描述JMS传输的供应商之间进行了自由的切换。这一点在上面引用的两段话中很明显。这种模棱两可的态度对任何事情都没有帮助

至少有一个实现(IBM的MQ)采用这样的方法:一个发布分成10条消息,创建了10条唯一的新消息,因此每个消息都有一个唯一的
JMSMessageID
值。这可能与第二段引文一致,该段要求唯一性的作用域是提供者,其中“提供者”似乎指的是供应商实现,而不是发送消息的对象

我相信,当一条已发布的消息散播到多个订阅者时,正确的行为应该是
JMSMessageID
将保留在消息的每个实例中,以便能够按照预期关联回复。换句话说,我认为IBM的实现是不符合要求的。由于规范在这个问题上是含糊不清的,我正在寻找一个权威的来源,它要么直接声明,要么强烈暗示规范所期望的行为,不管是哪种方式。根据响应的不同,我要么退出,要么将此问题作为法规遵从性缺陷向IBM提出。

这里的术语“提供者”仅指正在使用的特定消息传递产品,包括客户端和服务器端组件。为了避免混淆,我将在这里使用JMS产品供应商这个词

JMS规范的目的是定义由该消息传递产品实现的Java API。它使用诸如“提供者”之类的松散术语,因为JMS规范没有定义产品的体系结构,并且试图避免建议如何在客户端和服务器端组件之间共享实现,甚至避免建议是否存在服务器(或服务器集群)。你会注意到规范从来没有(好吧,几乎从来没有)说“服务器做这个”或“服务器做那个”

关于“唯一性的确切范围”的一句话使JMS产品供应商能够轻松实现生成
JMSMessageID
值的代码。这意味着生成
JMSMessageID
值的代码不需要担心生成的值在整个宇宙中是唯一的。这足以确保它们对于特定的产品安装是唯一的

您说“规范没有明确说明从发布API调用返回的
JMSMessageID
必须与使用时消息中存在的匹配。”

我认为这在第4.4.11节“如何设置消息头值”中有说明。这表明
JMSMessageID
是由“JMS提供者发送方法”设置的。同一节接着说,“由“JMS提供者发送方法”设置的消息头字段将在发送客户端和接收客户端上可用。”

这意味着在send()或publish()调用返回后,发送应用程序可以使用方法
getJMSMessageID()
查找分配给该消息的消息ID。当收到此消息时,接收应用程序可以使用相同的方法,并获得相同的值

发送到某个主题的每条消息都会传递给该主题上的每个订户。这些订阅者将收到相同消息的单独副本,具有相同的正文、属性和标题,包括
JMSMessageID
value


自由争论;JMS规范并非没有歧义。

我认为这里的问题不在于何时在已发布的消息上设置JMSMessageID字段,而在于在JMS提供程序中处理该消息时会发生什么

正如T.Rob和Nigel的文章所述,JMS 2.0规范第3.4.3节规定:

“JMSMessageID标头字段包含一个唯一 标识提供程序发送的每条消息。”

而且:

“JMSMessageID是一个字符串值,应该作为唯一的 用于在历史存储库中标识消息的键。确切的 唯一性范围由提供程序定义。它至少应包括所有 提供程序的特定安装的消息,其中 安装是一组已连接的消息路由器。“

也就是说