JMSMessageID应该在发布和订阅之间进行更改吗?

时间:2015-03-12 04:02:24

标签: jms ibm-mq

JMS 2.0规范说

  

JMSMessageID标头字段包含唯一的值   标识提供商发送的每条消息。

...和...

  

唯一性的确切范围是提供者定义的。它应该至少   涵盖了提供商的特定安装的所有消息   安装是一组连接的消息路由器。

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

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

此外,如果第一段中使用的“提供者”指的是发送消息的内容,那么散布到10条具有相同JMSMessageID值的相同消息的出版物将符合规范,因为唯一性在发送方测量。

不幸的是,规范在使用术语“提供者”来描述发送消息而不是用它来描述JMS传输的供应商之间切换。这在上面两个引用的段落中很明显。这种模棱两可并不重要。

至少有一个实现(IBM的MQ)采用的方法是,一个发布到10条消息的发布已经创建了10条唯一的新消息,因此每个消息都有一个唯一的JMSMessageID值。这可以说与第二个引用的段落一致,该段落需要作用于提供者的唯一性,其中“提供者”似乎指的是供应商实现,发送消息的事物。

我相信,当发布的消息向多个订阅者扇出时,正确的行为将是在消息的每个实例中保留{{1}},以便可以按预期关联回复。换句话说,我认为IBM的实施是不合规的。由于规范在这个问题上是模棱两可的,我正在寻找一个权威的来源,要么直接或强烈暗示规范所预期的行为,不管是这样还是另一种。根据响应,我要么退出,要么将IBM的问题作为合规性缺陷提出。

2 个答案:

答案 0 :(得分:7)

术语"提供者"这里只是对正在使用的特定消息传递产品的引用,包括客户端和服务器端组件。为避免混淆,我将在此处使用JMS产品供应商一词。

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

关于"确切唯一性范围的句子"是为了让JMS产品供应商能够轻松实现生成JMSMessageID值的代码。它表示生成JMSMessageID值的代码并不需要担心确保生成的值在整个Universe中是唯一的。足以确保它们对于特定产品安装而言是独一无二的。

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

我认为这在第4.4.11节和第34节中说明;如何设置消息标题值"。这表明getJMSMessageID()由" JMS提供程序发送方法"设置。同一部分继续说"消息头字段被定义为由' JMS提供者发送方法'将在发送客户端和接收客户端上提供。"

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

发送给主题的每条消息都会传递给该主题的每个订阅者。这些订阅者将收到相同邮件的单独副本,其中包含相同的正文,属性和标题,包括{{1}}值。

随意争辩; JMS规范并非没有歧义。

答案 1 :(得分:2)

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

如T.Rob和Nigel的帖子所述,JMS 2.0规范的第3.4.3节规定:

  

“JMSMessageID标头字段包含唯一的值   标识提供商发送的每条消息。“

还有:

  

“JMSMessageID是一个String值,应该作为唯一值   用于标识历史存储库中的消息的键。最正确   唯一性范围是提供者定义的。它应该至少涵盖所有   用于特定安装提供商的消息   安装是一组连接的消息路由器。“

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

该规范还在第4.2.1节中指出

  

“一个主题可以被认为是一个收集和支持的迷你消息代理   分发发给它的消息。依靠这个话题作为   中介,消息发布者保持独立于订阅者   反之亦然。“

这意味着规范的目的是,当消息被发送到主题时,主题可以对消息做一些工作,包括创建消息的多个副本(或者更具体地,创建多个消息)使用在提供者的存储库中被视为独立的相同数据。

最后,第4.2.2节说明:

  

“订阅将收到发送到的每封邮件的副本   创建订阅后的主题,...每个副本   消息被视为完全独立的消息。完成一项工作   复制对任何其他人没有影响;承认一个没有   承认任何其他;一条消息可以立即发送,而   另一个人等待消费者在它之前处理消息。“

将这些段落放在一起,规范可以解读为

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

    请求 - 响应范例是一个常见的范例,尽管使用基于pub-sub的分发模型,发送应用程序可能不得不应对多个响应,而不仅仅是那些更有可能采用点对点架构的响应。我们承认存在消息传递方案,其中消息id具有与IBM MQ当前实现的“唯一性”不同的“唯一性”的能力将为某些IBM MQ客户提供价值

    由于上述原因,IBM坚信其MQ JMS解决方案是合规的,因此不接受PMR。但是,我们确实承认有许多用例,维护消息ID对您有益。出于这个原因,我们将RFE 35062作为未提交的候选人,这意味着它具有最高的被解决概率,我们保证我们正在积极努力提供尽可能快地满足需求的解决方案。但要做到这一点,我们将非常感谢有关RFE的更多反馈,并描述了用户在此尝试解决的实际问题。例如,这是用于审计目的,请求 - 回复,消息流等,以及您需要复制的内容?我们获得的信息越多,解决方案就越有可能满足需求。