【问题标题】:Can a JMS subscriber client ID be migrated across hosts?能否跨主机迁移 JMS 订阅者客户端 ID?
【发布时间】:2011-03-15 18:48:00
【问题描述】:

我的任务在 JMS 主题上有一个持久订阅者,我需要能够将此任务从一个主机移动到另一个主机。

任务已使用以下方式设置其客户端 ID:

TopicConnection.setClientID("MyClient");

和:

TopicSession.createDurableSubscriber(主题, “耐用”);

对于TopicConnection、TopicSession和Topic的相关实例。我正在使用客户端确认,并且每条消息都会在成功处理后得到确认(我在下面发布的示例运行中没有错误)。

任务将始终具有相同的客户端 ID(“MyClient”和“durable”的组合)。

但是,对于每个主机来说,这个相同的客户端 ID 似乎被视为单独的。

所以我得到以下场景:

  1. 主机 A 正在运行订阅服务器。
  2. 已发送消息 1-10。
  3. 主机 A 收到消息 1-10 并关闭其订阅者(关闭连接)
  4. 已发送消息 11-20。
  5. 主机 B 使用(显然)相同的客户端 ID 设置订阅者
  6. 已发送消息 21-30。
  7. 主机 B 收到消息 11-30(通常是之前的一些消息,似乎是随机的)
  8. 主机 B 关闭其订阅者
  9. 主机 A 再次设置它的订阅者
  10. 主机 A 收到消息 11-30

我认为主机身份以某种方式被合并到后台的客户端 ID 中是否正确?有没有办法阻止这种情况发生。

我正在使用 SwiftMQ,以防这是该解决方案特有的行为。

【问题讨论】:

  • 我应该指出主机 B 上的路由器在步骤 1-4 中没有运行。

标签: java jms


【解决方案1】:

我对持久订阅者如何工作的理解(假设在第 8 步中一切都正确关闭。)与您的相同(这似乎是一个错误)。我从未见过任何表明持久订阅(或任何 jms 订阅)与特定主机相关联的东西。这似乎会破坏构建强大系统的任何尝试(即,如果原始主机崩溃,您就会陷入困境)。

【讨论】:

    【解决方案2】:

    好的,我们已经知道为什么会这样了。

    我们集群中的每台服务器都维护着自己的 JMS 路由器。在 SwiftMQ(如果不是所有 JMS 实现)中,持久订阅依赖于位置。由于每个路由器都维护自己的持久订阅列表,因此将分别管理不同路由器上的两个持久订阅,即使它们具有相同的客户端 ID。

    【讨论】:

    • 这种行为似乎也有优势。如果您有同一个客户端的多个实例,您将如何保证这些客户端中的每一个都具有全局唯一的客户端 ID?在 Java 代码中,这可能是可行的(生成 UUID,将其保存在本地等),但是当通过一些管理界面或 xml 文件维护订阅时,这将非常非常困难。
    • 我们的模型依赖于一次只有一个特定类型的客户端,因此它们都重复使用相同的客户端 ID。如果两个错误启动(一个一个路由器),第二个将被拒绝,因为它的 ID 不是唯一的。
    • 虽然我把这个问题留了下来,以防其他人对 SwiftMQ 的性质有类似的误解。我可以理解这种方式是有原因的(将跨多个路由器的每个订阅关联起来将是一场噩梦)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-17
    • 1970-01-01
    • 2018-08-14
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    • 2015-04-06
    相关资源
    最近更新 更多