如何可靠地发送 JMS 消息? (故障转移 MessageProducer.send() 错误)

发布于 2024-10-07 05:13:53 字数 214 浏览 0 评论 0原文

是否可以可靠地将 JMS 消息发送到目的地?我所说的可靠是指确保如果 MessageProducer.send() 调用由于某种原因失败,它将自动重试。我意识到事务会话可能会使用 .recover() 作为最后的手段,但是重试怎么样?例如,我在建立会话和尝试发送消息之间出现间歇性网络故障。在这种情况下,recover() 有什么帮助?

Is it possible to reliably send JMS message to the destination? By reliably I mean ensuring that if e.g. MessageProducer.send() call fails for some reason, it will be retried automatically. I realize that transaction session may use .recover() as last resort, but what about retrying? E.g. I have intermittent network failure in between session was established and attempted to send a message. How would recover() help in this case?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

九厘米的零° 2024-10-14 05:13:53

据我所知,JMS不支持这种行为。您可以在特定的供应商扩展中进行搜索,但是,恕我直言,您不太可能找到适合您需求的东西。

对于您的问题,我只看到两种解决方案:

  1. 实施它。您可以手动管理 JMS 会话,捕获任何异常,并在需要时使用事务管理器的“仅设置回滚”功能来使事务无效。

  2. 使用本地队列存储消息并使用后台服务将它们移动到目标远程队列。请注意,许多队列管理器都支持这一点,例如存储和转发ActiveMQ的队列。显然这样,你的事务边界将不包括远程队列。

我知道第二个解决方案并不能完全解决您的问题,但很多时候,它就足够了。

As far as I know, JMS do not support such behavior. You could search among specific vendor-extensions but, IMHO, it is unlikely that you find something suitable to your needs.

I see only two solutions to your problem:

  1. Implement it. You can manage the JMS session manually, catch any exception and, if needed, use "set rollback only" function of transaction manager to invalidate the transaction.

  2. Use a local queue to store messages and use a background service to move them to target remote queue. Note that many queue manager support this, e.g. Store and forward Queues of ActiveMQ. Obviously this way, your transaction boundary will not include remote queue.

I know that 2nd solutions is not a full answer to your problem but, many times, it is sufficient.

面如桃花 2024-10-14 05:13:53

JMS 没有指定您正在寻找的行为。事实上,JMS 专门解决了由于网络故障而导致的问题,它指出您可能会两次收到相同的消息,并将其称为“功能重复”消息,因为从 JMS 代理的角度来看,它只被传递一次。

由于这不是 JMS 的一部分,您的答案在于不同的供应商实现。例如,从 v7.0.1 开始,WebSphere MQ 有一个称为“多实例队列管理器”的功能。 v7.0.1 客户端应用程序将自动重试连接,甚至在发生故障时遵循 QMgr 从主节点到辅助节点。发生这种情况时应用程序会阻塞,并且不知道故障转移。

然而,即使有这种行为,您的应用程序仍然需要针对失败进行编码。例如,如果使用 WMQ 自动重新连接(或任何提供商的重新连接),您可能需要调整应用程序可能阻止等待恢复连接的时间长度,以便用户不会遇到无限期挂起的情况。当调用解除阻塞时,事务将回滚,并且任何重试都必须在代码中进行。这是适当的,因为事务与不再有效的连接关联。

JMS doesn't specify the behavior you are looking for. In fact, JMS specifically addresses problems due to network failure by noting that you may get the same message twice and calls this a "functionally duplicate" message since from the point of view of the JMS broker, it has only been delivered once.

Since this is not part of JMS your answer lies in the different vendor implementations. For example, WebSphere MQ has a feature called "Multi-Instance Queue Manager" as of v7.0.1. A v7.0.1 client application will automatically retry the connection and even follow the QMgr from the primary to the secondary node in the event of a failure. The application blocks while this occurs and is not aware of the failover.

However, even with this behavior, your app still needs to code for the failure. For example, if using the WMQ automatic reconnect (or any provider's reconnect for that matter) you probably want to tune the length of time the app might block waiting to recover the connection so that the user doesn't experience an indefinite hang. When the call unblocks, the transaction is rolled back and any retry must occur in the code. This is appropriate since the transaction is associated with a connection that is no longer valid.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文