是否可以可靠地将 JMS 消息发送到目的地?可靠地我的意思是确保如果例如MessageProducer.send()
调用由于某种原因失败,它将自动重试。我意识到事务会话可能.recover()
用作最后的手段,但是重试呢?例如,我在会话建立和尝试发送消息之间出现间歇性网络故障。recover()
在这种情况下会有什么帮助?
2 回答
据我所知,JMS 不支持这种行为。您可以在特定的供应商扩展中进行搜索,但恕我直言,您不太可能找到适合您需求的东西。
我只看到您的问题的两种解决方案:
实施它。您可以手动管理 JMS 会话,捕获任何异常,并在需要时使用事务管理器的“仅设置回滚”功能使事务无效。
使用本地队列存储消息并使用后台服务将它们移动到目标远程队列。请注意,许多队列管理器都支持这一点,例如ActiveMQ 的存储和转发队列。显然这样,您的事务边界将不包括远程队列。
我知道第二个解决方案不是您问题的完整答案,但很多时候就足够了。
JMS 没有指定您正在寻找的行为。事实上,JMS 通过指出您可能会收到两次相同的消息并将其称为“功能重复”消息来专门解决由于网络故障引起的问题,因为从 JMS 代理的角度来看,它只被传递一次。
由于这不是 JMS 的一部分,因此您的答案在于不同的供应商实现。例如,WebSphere MQ 从 v7.0.1 开始就有一个称为“多实例队列管理器”的特性。v7.0.1 客户端应用程序将自动重试连接,甚至在发生故障时跟随 QMgr 从主节点到辅助节点。发生这种情况时应用程序会阻塞并且不知道故障转移。
但是,即使有这种行为,您的应用程序仍然需要为失败编写代码。例如,如果使用 WMQ 自动重新连接(或任何提供程序的重新连接),您可能希望调整应用程序可能阻止等待恢复连接的时间长度,以便用户不会遇到无限期挂起。当调用解除阻塞时,事务将回滚,并且必须在代码中进行任何重试。这是适当的,因为事务与不再有效的连接相关联。