我正在尝试找到有关在订阅者失败时如何通知 EMS 发布者的答案。在Publisher->EMS server->Subscriber的情况下,如果Subscriber出现故障,我需要通知Publisher采取纠正措施。我不关心durabilty/PERSIETENCE,我的意义在于时间。在交易系统中,如果我向订阅者发送市场订单,订阅者又将其发送到交易所,如果失败,我需要让我的发布者将不同主题的消息发布到另一个订阅者(另一个交易所)。任何想法表示赞赏。
2 回答
tibjmsadmin.jar 库包含检测订阅者何时断开连接的方法。比编写代码更容易,您可以:
- 如果您有 Hawk,请使用 tibjmsadmin.hma 在订阅者断开连接时编写 Hawk 规则,或者
- 监听监控主题 $sys.monitor.connection.disconnect - 消息正文告诉您哪个订阅者断开了连接。
然而,这些对发布者进行故障转移的“监控”方法存在一个重大问题 - 在您检测订阅者故障并重定向发布者所需的时间中,一些消息可能会通过并卡在失效队列中。你不会看到这种情况发生在任何 1000 万美元的交易中!
EMS 知道订阅者何时连接或未连接,您应该利用这一点。
使用“分布式队列”,应该不需要在应用程序中编写逻辑代码,以便在失败时切换到新订阅者。这种情况不会丢失消息并保持消息的顺序。将负载平衡和故障转移逻辑保留在代码之外以及 JMS 提供程序的管理设置中也是一种很好的架构实践。
基本上,您将多个订阅者设置到一个队列(每个交换由一个订阅者表示)。默认操作是 EMS 以循环方式在您的订阅者之间平衡消息负载。但是您可以将队列设置为“独占”,这样消息一次只能发送给一个订阅者。然后,如果该活动订阅者失败,则将消息转发给另一个订阅者。
有关所有这些主题的更多详细信息,请参阅 EMS 手册。
不确定您是否有权访问,您可以尝试查看 QueueInfo 或 TopicInfo 中的 ReceiverCount 或 ConsumerCount - 我相信您需要 tibjms.admin 包。也许您可以在发布之前查询此内容,然后有选择地发布?不确定开销是多少。
由于 JMS 的性质,AFAIK 没有事务状态(除非您使用 XA 事务 - 具有所有这些开销)或确认将通过 EMS 代理传播。Ieack 总是在发布者和代理以及消费者和代理之间。
如果上述情况失败,您可以尝试一个单独的 ack 主题,其角色被颠倒,但失败情况是超时 - 我不确定这是否明智。
如果您并不真正关心订单流向哪个交换 - 为什么不让主题/队列独占并让两个消费者都尝试消费 - 第一个成功的将处理所有消息 - 如果它死了,那么第二个(可能会定期重试 - 可能会成功连接).. 或者允许两者都处理队列外的订单 - 请记住一条消息只会由单个消费者处理......
在您的订单流中,我真的看不到解耦消息总线的优势……对我来说毫无意义……