如何找出JMS Connection是否存在?

在JMS中,很容易发现连接是否丢失,发生exception。 但是我怎么知道连接是否再次存在?

场景:我使用JMS与我的服务器通信。 现在我的连接断开(服务器关闭),这导致exception。 到现在为止还挺好。 如果服务器再次启动并重新建立连接,我该如何知道?

我没有看到任何能够提供此类信息的听众。

啊……旧的exception处理/重新连接难题。

有些传输提供商会自动为您重新连接您的应用程序,以及一些使应用程序驱动器重新连接的应用程序。 通常,重新连接会将exception隐藏在应用程序之外。 缺点是,如果所有远程消息传递节点都关闭,您不希望应用程序永久挂起,因此最终必须包含一些重新连接逻辑。

现在这里是有趣的部分 – 如何以提供商中立的方式处理exception? JMSexception实际上毫无价值。 例如,“安全性exception”可能是Java安全策略过于严格,文件系统权限过于严格,LDAP凭据失败,传输连接失败,队列或主题打开失败或任何其他许多与安全相关的问题。 它是链接的exception,它具有来自传输提供程序的详细信息,可以帮助调试问题。 我的客户一般采取三种不同的方法之一……

  1. 对所有错误都一视同仁。 关闭所有对象并重新初始化它们。 这是JMS便携式。
  2. 允许应用程序检查链接的exception,以区分致命错误和瞬态错误(即auth错误与队列已满)。 不提供便携式。
  3. 特定于提供程序的error handling类。 另外两个的混合体。

在您的情况下,队列和主题对象可能仅在原始连接的上下文中有效。 假设提供者自动重新连接您获得exception的事实意味着重新连接失败,并且无法恢复队列和主题对象的上下文。 关闭所有对象并重新连接。

您是否想要做更多特定于提供者的事情,例如区分瞬态错误和永久性错误,这是“依赖”的事情之一,您必须根据具体情况来解决这个问题。

监视连接exception的最佳方法是设置exception监听器,例如:

ConnectionFactory connectionFactory = (ConnectionFactory) context.lookup("jmsContextName"); connection = connectionFactory.createConnection(); connection.setExceptionListener(new ExceptionListener() { @Override public void onException(JMSException exception) { logger.error("ExceptionListener triggered: " + exception.getMessage(), exception); try { Thread.sleep(5000); // Wait 5 seconds (JMS server restarted?) restartJSMConnection(); } catch (InterruptedException e) { logger.error("Error pausing thread" + e.getMessage()); } } }); connection.start(); 

JMS规范没有描述任何传输协议,它没有说任何关于连接的事情(即代理应该保持它们存活或为每个会话建立新的连接)。 所以,我想你的意思是什么

现在我的连接断开(服务器关闭),这导致exception。

是你正在尝试发送消息,你得到一个JmsException。

我认为,查看经纪人是否正常的唯一方法是尝试发送消息。

基于连接的JMSException的唯一选择是尝试在exception处理程序中重新建立连接,然后重试该操作。