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

时间:2010-12-13 12:28:53

标签: java jms reliability

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

2 个答案:

答案 0 :(得分:1)

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

我只看到两个问题的解决方案:

  1. 实施它。您可以手动管理JMS会话,捕获任何异常,如果需要,还可以使用事务管理器的“set rollback only”功能使事务无效。

  2. 使用本地队列存储消息并使用后台服务将其移动到目标远程队列。请注意,许多队列管理器支持此功能,例Store and forward Queues of ActiveMQ。显然这样,您的事务边界将不包括远程队列。

  3. 我知道第二种解决方案不能完全解决您的问题,但很多时候,这已经足够了。

答案 1 :(得分:1)

JMS未指定您要查找的行为。实际上,JMS专门解决了由于网络故障导致的问题,因为它注意到您可能会获得两次相同的消息,并将其称为“功能重复”消息,因为从JMS代理的角度来看,它只被传送一次。

由于这不是JMS的一部分,因此您的答案在于不同的供应商实施。例如,WebSphere MQ具有一个名为“Multi-Instance Queue Manager”的功能,自v7.0.1起。 v7.0.1客户端应用程序将自动重试连接,甚至在发生故障时遵循QMgr从主节点到辅助节点。发生这种情况时应用程序会阻塞,并且不知道故障转移。

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