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

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

JMS 2.0规范说

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

……还有

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

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

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

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

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

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


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

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

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

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

您可以说,该规范没有明确声明从发布API调用返回的JMSMessageID必须与消息中的JMSMessageID匹配

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

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

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

自由争论;JMS规范并非没有歧义<
/p> 我认为这里的问题不在于何时在已发布的消息上设置JMSMessageID字段,而在于在JMS提供程序中处理该消息时会发生什么

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

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

而且:

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

也就是说,如果两个或多个消息在存储库中构成不同的消息,则即使它们包含相同的数据,也应该具有不同的JMSMessageID值

本规范第4.2.1节还规定

一个主题可以被看作是一个小型消息代理,它收集 分发发往它的邮件。以主题为基础 作为中介,消息发布者独立于订阅者 反之亦然

这意味着规范的意图是,当消息被发送到主题时,主题可以对消息执行一些工作,包括创建消息的多个副本,或者更具体地说,创建具有相同数据的多个消息,这些数据在提供者的存储库中被认为是独立的

最后,第4.2.2节规定:

订阅将收到发送到的每条邮件的副本 创建订阅后的主题。。。每份 消息被视为完全独立的消息。在一台计算机上完成的工作 副本对任何其他文件无任何影响;承认一个人并不重要 承认任何其他;一条消息可以立即发送,而 另一个等待其消费者提前处理消息

把这些段落放在一起,规范可以理解为

将消息发送到主题时,该主题可以为每个当前订阅创建消息的副本。 发送到主题时创建的消息副本可以视为完全独立的消息。 由于单独的JMS消息由其JMSMessageID字段唯一标识,因此每个单独的订阅消息都应该具有不同的JMSMessageID 为了理解Nigel的最后一句话,JMS规范并非没有歧义。这是非常正确的,供应商和客户之前已经解决了这些问题,专家组的工作确实是为了澄清这些问题,提供指导,并提出改进合规性测试的建议。基于上述理解,以及IBM MQ v8通过的JMS 2.0符合性测试套件中的测试,IBM MQ v8实现符合JMS2.0,同样,早期的IBM MQ版本也符合JMS1.1;JMS 1.1规范具有同样的模糊性

请求-响应范例是一种常见的范例,尽管在基于发布-订阅的分发模型中,发送应用程序可能需要处理多个响应,而不仅仅是点式体系结构中更可能出现的响应。我们承认,在某些消息传递场景中,消息id与IBM MQ当前实现的消息id具有不同的“唯一性值”的功能将为某些IBM MQ客户提供价值


出于上述原因,IBM坚信其MQ JMS解决方案是兼容的,因此不会接受PMR。但是,我们承认,在许多用例中,维护消息ID对您是有益的。出于这个原因,我们将选择一个未承诺的候选人,这意味着它有最高的被解决的可能性,我们承诺,我们将积极努力,尽快提供最适合需求的解决方案。但要做到这一点,我们希望在RFE上有更多的反馈,并描述我们的用户在这里试图解决的实际问题。例如,这是否用于审计目的、请求-答复、消息流等,以及您需要复制的内容?我们掌握的信息越多,解决方案越有可能满足需求。

一位客户问了我类似的问题。他们正在从P2P模式转向发布/订阅消息模式。他们的发送方应用程序缓存邮件ID,以便以后进行对账。当使用P2P时,他们的发送方应用程序正确地从MQMD获取唯一的消息ID。但是切换Pub/Sub时,消息ID变为零,它们不能使用这样的消息ID。祝您好运,找到规范中所写之外的权威来源!说真的,我的意思是,我希望你能幸运地找到这样一个来源,一旦找到,我们可能有很多问题要问。我在Twitter上ping了Nigel Deakin@JMS_Spec,并链接到了这个问题。这是最权威的
但是没有得到他的回复,我想在WebLogic或AQ文档中可能有一些东西暗示了正确的行为。尽管如此,IBM还是应该解决这个问题。规范以一种需要保留ID的方式讨论请求/应答,并且似乎很清楚其意图是什么。MQ做了什么打破了这个。谢谢,奈杰尔!我将把任何争论留给IBM,因为这是我期待的答案-谢谢你,马特!我想这对我来说就是范围界定。您可以说,两个或多个消息,即使它们包含相同的数据,如果它们在存储库中构成不同的消息,也应该具有不同的JMSMessageID值。对我们许多人来说,这是同一信息的不同实例。从逻辑上讲,它们是相同的消息,它们作为单独的物理拷贝存在,这是我们应该避免的IBM实现细节。正如Nigel所描述的那样,看看JMS组如何解决测试套件和规范意图之间的差异会很有趣。