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

Java 如何可靠地发送JMS消息?(故障转移MessageProducer.send()错误),java,jms,reliability,Java,Jms,Reliability,是否可以将JMS消息可靠地发送到目标?所谓可靠,我的意思是确保如果例如MessageProducer.send()调用由于某种原因失败,它将自动重试。我意识到事务会话可能会使用.recover()作为最后手段,但重试又如何呢?例如,在建立会话并尝试发送消息的过程中,我遇到间歇性网络故障。在这种情况下,recover()有什么帮助?据我所知,JMS不支持这种行为。您可以在特定的供应商扩展中搜索,但是,依我看,您不太可能找到适合您需要的东西 我认为只有两种方法可以解决您的问题: 实施它。您可以手动管

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

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

我认为只有两种方法可以解决您的问题:

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

  • 使用本地队列存储消息,并使用后台服务将消息移动到目标远程队列。请注意,许多队列管理器都支持此功能,例如。显然,通过这种方式,您的事务边界将不包括远程队列


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

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

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


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

    是的,JMS可以是完全事务性的。然而,问题的方式和原因很复杂,你的问题太模糊,无法详细说明。谢谢你的回答!我应该提供哪些细节来获得更详细的答案?我在谷歌上搜索“jms可靠地发送消息”,但这并没有产生有意义的结果。您能否就如何实现可靠的发送(从生产者到目的地)给出一些提示?谢谢您正在使用哪个队列管理器?哪种事务管理器抽象(例如jee、spring)?可移植性和实现独立性是很强的要求吗?