Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何确定是否存在JMS连接?_Java_Jms - Fatal编程技术网

Java 如何确定是否存在JMS连接?

Java 如何确定是否存在JMS连接?,java,jms,Java,Jms,在JMS中,很容易发现如果连接丢失,就会发生异常。但是我怎么才能知道连接是否再次存在 场景:我使用JMS与服务器通信。现在,我的连接中断(服务器关闭),导致异常。到现在为止,一直都还不错。如果服务器再次启动并重新建立连接,我怎么知道 我看不到任何监听器会促进这些信息。JMS规范没有描述任何传输协议,它没有说明任何关于连接的内容(即,代理应该让它们保持活动状态或为每个会话建立新连接)。所以,我想你的意思是 现在,我的连接中断(服务器关闭),导致异常 你试图发送一条消息,却收到了JmsExcepti

在JMS中,很容易发现如果连接丢失,就会发生异常。但是我怎么才能知道连接是否再次存在

场景:我使用JMS与服务器通信。现在,我的连接中断(服务器关闭),导致异常。到现在为止,一直都还不错。如果服务器再次启动并重新建立连接,我怎么知道


我看不到任何监听器会促进这些信息。

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

现在,我的连接中断(服务器关闭),导致异常

你试图发送一条消息,却收到了JmsException


我认为,查看代理是否启动的唯一方法是尝试发送消息。

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

Ahhh…旧的异常处理/重新连接难题

有些传输提供商会自动为您重新连接应用程序,有些则会重新连接应用程序驱动器。通常,重新连接会对应用程序隐藏异常。不利的一面是,如果所有远程消息传递节点都已关闭,您不希望应用程序永远挂起,因此最终,您必须包含一些重新连接逻辑

现在有一个有趣的部分-如何以与提供者无关的方式处理异常?JMS异常实际上毫无价值。例如,“安全例外”可能是Java安全策略限制太严格、文件系统权限限制太严格、LDAP凭据失败、到传输的连接失败、队列或主题打开失败或其他几十个安全相关问题中的任何一个。正是链接异常包含了传输提供程序提供的详细信息,才真正有助于调试问题。我的客户通常采取三种不同的方法之一

  • 对所有错误一视同仁。关闭所有对象并重新初始化它们。这是JMS可移植的
  • 允许应用程序检查链接的异常,以区分致命错误和暂时错误(即身份验证错误与队列已满)。不可移植
  • 提供程序特定的错误处理类。另外两个的混合体
  • 在您的情况下,队列和主题对象可能仅在原始连接的上下文中有效。假设提供程序自动重新连接,则您遇到异常意味着重新连接失败,并且无法恢复队列和主题对象的上下文。关闭所有对象并重新连接


    您是否要执行更特定于提供程序的操作,例如区分暂时性错误和永久性错误,这是“取决于”的事情之一,您必须根据具体情况来确定这一点。

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

    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是一种异步协议,所以实现可以暂时建立连接——仅仅因为连接成功并不意味着队列现在仍然可用。问题是,如果我有一个GUI客户端,它通过JMS与服务器通信,在队列中充斥无法处理的消息是没有意义的,因为服务器已关闭。因此,我想唯一现实的选择是每隔一段时间(ttl较低)发送一次“ping”,以检查是否仍然可以(或再次)与服务器通信。这是您推荐的方法吗?这是一种常见的方法。例如,默认情况下,WebSphereMQExplorer将每15秒刷新一次与队列管理器的连接。如果API调用失败,则在客户端中驱动重新连接。如果这样做有效,GUI只需要额外的一秒钟来响应。如果失败,GUI将获得异常并驱动自己的重新连接逻辑。在应用程序的情况下,我通常建议人们将插装调用设计到他们的API中,比如非事务性的“ping”,正是出于这个原因看起来像什么?