【问题标题】:Can durable subscriptions survive client restart?持久订阅能否在客户端重启后继续存在?
【发布时间】:2011-03-18 14:40:28
【问题描述】:
如果我使用持久订阅,我可以重新启动客户端并重新订阅而不会丢失任何消息吗? (假设我的客户没有以任何方式取消订阅。假设它只是崩溃了)。
让我澄清一下。 JMS 1.1 规范说明如下:
9.3.3.2 使用持久订阅重新连接到主题
/* Reconnect to a durable subscription */
session.createDurableSubscriber(newsFeedTopic, "mySubscription");
但是,有一些重要的限制需要注意:
- 客户端必须附加到同一个连接。
- 目标名称和订阅名称必须相同。
- 如果指定了消息选择器,它也必须相同。
“相同的连接”部分让我很感兴趣。目前尚不清楚在这种情况下“相同”是什么意思。
【问题讨论】:
标签:
java
jms
message-queue
messaging
【解决方案1】:
如果持久订阅没有活动订阅者,JMS 会保留订阅的消息,直到订阅者收到它们,或者直到它们过期,或者直到持久订阅被删除。这使订阅者应用程序可以在一段时间内与 JMS 提供者断开连接,然后重新连接到提供者并处理在他们不在期间发布的消息。
【解决方案2】:
在规范中,请看 4.3,其中提到 Connection 对象可以包含唯一的客户端标识符,而 4.3.2 则说明...
客户端标识符的目的是关联一个连接和它的对象
由提供商代表客户维护的状态。根据定义,
由客户端标识符标识的客户端状态只能由一个客户端在
一次。 JMS 提供者必须防止并发执行的客户端使用
它。
因此,这里的意图是持久订阅包含一个唯一标识符,以便当应用重新订阅时,它可以附加到正确的状态存储,在该状态存储中,消息已在其不存在时排队。由于这样做的首选方法是在特定于客户端的连接对象中编码标识符,因此规范指示您使用相同的连接重新连接,但在这种情况下,这意味着 same 受管理的对象 不同的连接句柄(使用 WMQ 术语)。
当然,您不需要管理对象,应用程序可以动态生成连接。在这种情况下,您需要安排它使用相同的客户端标识符进行连续订阅。