持久队列和主题如何工作
常见问题解答 > JMS > 持久队列和主题如何工作
持久队列会持久地保留消息,以便任何合适的消费者都可以消费它们。持久队列不需要关心将来哪个消费者将消费这些消息。只有一份消息副本,未来的任何消费者都可以消费它。
然而,持久主题则不同,因为它们必须在逻辑上为每个持久消费者持久保存每个合适消息的实例——因为每个持久消费者都会收到自己的消息副本。
例如,想象一个持久订阅者 S 在时间 D1 启动,订阅主题 T。一些发布者向该主题发送消息 M1、M2、M3,S 将收到这些消息。然后 S 停止,发布者继续发送 M4、M5。
当 S 在 D2 重新启动时,发布者发送 M6 和 M7。现在 S 将收到 M4、M5 以及随后的 M6 和 M7 以及所有将来的消息。也就是说,S 将收到从 M1 到 M7 的所有消息。
这就是持久消费和非持久消费之间的区别。如果 S 是非持久消费者,那么它只会收到 M1、M2、M3 和 M6、M7——而不是 M4 和 M5。也就是说,因为订阅是持久的,所以无论订阅者是否正在运行,S 都将收到发送到 T 的所有消息。对于非持久主题,只传递到主题 T 的正在运行的 S 的消息会被传递。
因此,对于持久主题订阅,JMS 提供者需要能够在 S 关闭时识别它,并在将来重新连接时识别它,以便它知道在 S 未运行时发送哪些消息。JMS 规范规定,S 的识别是通过客户端 ID 和持久订阅者名称的组合来完成的。这样,S 使用的 JMS 连接就可以在不同的主题上拥有许多不同的持久订阅,或者在同一个主题上拥有具有不同选择器的多个持久订阅——但 JMS 提供者可以知道为哪个订阅保留哪些消息。
因此,在 JMS 连接上设置客户端 ID 是至关重要的(以及使用明智的持久消费者名称)以进行持久主题订阅。对于其他 QoS 来说这不是问题。