繁体   English   中英

如何知道何时失去与JMS主题的连接?

[英]How to know when connection to a JMS Topic is lost?

我有一个Java富客户端应用程序,它在启动时在远程HornetQ JMS主题上注册了持久订阅。 但是,如果服务器重新启动,则连接将丢失,并且只能通过重新启动客户端应用程序来恢复。 这会导致混乱的情况,即没有收到JMS消息,并且在客户端重新启动后立即收到很多消息。

一种简单的恢复连接的解决方案是运行计时器以定期检查连接是否仍然有效,否则尝试重新连接。 或者,如果在一定时间后仍未收到心跳,则服务器可以向客户端发送心跳,并尝试重新连接(如此答案中所述 )。

但是,这两种方法似乎都很难解决这个问题,因此,我想知道是否有更好的解决方案来确定该连接不再可用?

要获得断开连接的通知,必须在启动连接之前在TopicConnection上注册ExceptionListener

private void subscribe() throws JMSException {

    // get context / create connection and session / etc.
    TopicConnection connection = ...

    connection.setExceptionListener(this::handleExceptions);
    connection.start();
}

ExceptionListener您可以检查收到的JMSException的错误代码。 (错误代码是特定于供应商的)
对于HornetQ,连接DISCONNECT会收到错误代码DISCONNECT

private static final String HORNETQ_DISCONNECT_ERROR_CODE = "DISCONNECT";

private void handleExceptions(final JMSException jmsException) {

    final String errorCode = jmsException.getErrorCode();
    if (HORNETQ_DISCONNECT_ERROR_CODE.equals(errorCode)) {
        tryConnect();
    }
}

然后,您可以启动一个自取消计时器,该计时器尝试每隔x秒重新连接一次,直到成功为止。

private static final long SUBSCRIBE_RETRY_TIME_OUT_IN_MILLIS = 60000;

private void tryConnect() {

    final Timer timer = new Timer("JMS-Topic-Reconnection-Timer", true);
    final TimerTask timerTask = new TimerTask() {

        @Override
        public void run() {
            try {
                subscribe();
                // cancel the timer, after the subscription succeeds
                timer.cancel();
            }
            catch (final Exception e) {
                logger.info("reconnect to jms topic failed: {}", e.getMessage());
            }
        }
    };
    timer.schedule(timerTask, SUBSCRIBE_RETRY_TIME_OUT_IN_MILLIS, SUBSCRIBE_RETRY_TIME_OUT_IN_MILLIS);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM