我正在阅读Java EE教程的这一部分。 http://download.oracle.com/javaee/6/tutorial/doc/bncfu.html#bncfy
并且有一个问题:如果我有一个生成消息并将它们发送到服务器上的目标队列的JMS客户端(而不是服务器),那么这个producer.setDeliveryMode(DeliveryMode.PERSISTENT);仍然适用?
我的意思是JMS客户端是否支持任何保留消息的机制,或者只提供提供商/服务器软件?
由于
答案 0 :(得分:6)
由于JMS只是一个规范,因此没有什么能阻止实现在客户端提供某种级别的消息持久性。但是,在实践中,所有实现(无论如何我都知道)将其委托给代理。
请记住,消息传递最初设计为在每个节点上都有一个代理,就像每个节点也有一个TCP / IP,LU6.2或其他传输堆栈一样。从这个意义上讲,消息传递严格地说是一种传输,而不是像数据库这样的中央服务。其目的是提供一种本地服务,使应用程序与网络不可用以及可用的无数同步传输协议隔离开来。在此模型中,代理始终本地,并且唯一的网络通信是在两个代理之间。
多年来,消息传递增加了客户端功能,但这更多是关于许可成本而不是架构。消息传递客户端连接重新引入了对传输最初旨在保护应用程序的同步网络连接的依赖性。正如您的问题所示,我们现在已经完全循环 - 需要本地排队来保护应用程序免受网络不可用的影响。除了现在需要消息的本地持久性的应用程序实际上是(据称)异步消息传递应用程序。
我们当然可以建立一个本地迷你经纪人,在邮件到达中央经纪人之前对其进行排队。但在我们开始使客户端代码变得更加复杂之前(并且邀请无限递归来支持我们的异步消息传递以及更多异步消息传递)我建议再看看原始消息传递体系结构 - 将代理本地放在需要的应用程序中那种持久性。
一种方法是将服务提供商应用程序与服务使用者应用程序区别对待。服务提供者需要深度,持久的消息存储,并且因为它们通常是事务性的,所以不允许故障转移到代理的不同实例(在这种情况下,由XA资源管理器识别的“不同”)。 / p>
另一方面,简单的请求/回复应用程序可以继续通过网络匿名连接到轻量级的代理,而不需要永久队列。这些应用程序在同步点之外发出请求消息,并等待动态队列上的回复。如果他们进行故障转移,他们可以重新发出请求,并且回复将转到新节点。这些是联网的基于客户端的消息传递的理想候选者,因为它们与特定代理没有亲和力。只要客户端和服务器应用程序之间存在网络跳跃,就不需要确保客户端使用服务器等进行故障转移。服务提供商拥有本地代理,服务使用者可以连接两个(或更多)轻量级中央代理
当然,这不符合每个异步消息传递要求,但它确实提供了一种解决方案,为记录系统提供最高可靠性,并通过允许服务请求者共享集中式代理来保留许可成本。
答案 1 :(得分:1)
简短的回答是肯定的,它确实适用。实际上,它意味着由生成客户端的消息指定,以告诉代理如何处理它。
保持本地持久性没有多大意义,因为如果代理(服务器)关闭,在尝试使用producer.send(..)时会遇到JMSException。
-Ed Y。