2014-02-23 26 views
3

考虑使用JMS将消息发送到远程JMS队列的独立Java main()程序(无Java EE容器)。创建一个可靠的JMS客户端?

据我所知,如果远程队列由于某种原因(网络问题,服务器故障,队列满......)不可用,messageProducer.send(msg)将引发异常。

我是否必须自己实现重试逻辑,还是将JMS-api以某种方式解决此问题?

TextMessage message = session.createTextMessage(); 
    message.setJMSDeliveryMode(DeliveryMode.PERSISTENT); 
    MessageProducer mp = session.createProducer(topic); 
    mp.send(message); // Throws JMSException. How to retry, local storage etc? 
+1

我不知道,但看起来像你必须添加重试尝试逻辑。 – Kick

回答

1

你必须自己实现重试逻辑。请注意,如果连接失败无法再使用,则需要创建新的连接才能重试。

1

我想补充一点,通常使用客户端连接,你甚至不得不实现重试逻辑,但更多的,因为你永远不能确定发送失败的步骤。 你可能会把你的消息成功,但服务器没有发送给你关于它的信息,那么你有异常但消息在那里...这是一个有点虚构的例子,但仍然...

我会推荐你要执行一种协调的事务,你使用事务从一个源(例如文件系统或数据库)获取消息,然后将它发送到队列。如果一切都很好,你会提交jms会话,然后提交源文件(例如文件系统)操作。 这可能是一个HA事务,或者简单的伪HA - 按我描述的那样协调,它更轻量级,并且仍然提供一些容错。

然后执行重试逻辑,您可以在那里对您的数据传递的资源(数据库的文件系统)进行简单的轮询,因此下一次轮询失败的消息时,如果它回滚 - 您只需重新获取它并像往常一样使用它。

0

如果您使用WebLogic for JMS,则可以使用JMS SAF客户端从客户端获得可靠的传递。可以在这里找到更多信息Weblogic SAF client

+0

是的,但我的客户是独立的(没有jee容器)。 –

1

如果网络blip等连接存在问题,JMS提供程序(如WebSphere MQ)具有自动重新连接功能,JMS客户端在执行期间尝试重新连接时存在连接问题API。例如,如果在执行Send API期间连接到JMS提供程序中断,则JMS客户端尝试重新连接到JMS提供程序,并且如果建立了连接,则会向提供程序发送消息。重新连接尝试对JMS应用程序是透明的,这意味着应用程序不知道重新连接。

在队列已满的情况下,应用程序将不得不处理异常并采取适当的措施。

+0

是的,但我的客户是独立的(没有jee容器)。 –

+0

重新连接功能内置于MQ JMS客户端中。它可以由独立应用程序使用,不需要JEE容器。请参阅此链接:http://pic.dhe.ibm.com/infocenter/wmqv7/v7r5/topic/com.ibm.mq.dev.doc/q032520_.htm – Shashi

0

这取决于您的客户端运行的时间。如果它像一个桌面应用程序,即它运行一段时间,您可以在客户端上使用本地队列,并配置一个桥梁来照顾可靠的,一次又一次转发到远程队列。如果它是一个只被调用一次的脚本并退出,那么你必须为自己处理重试,幂等等......也许你会更好地使用同步调用。