java - 最初和已经获得先前连接后重新连接到 JMS 服务器

标签 java connection jms weblogic

我遇到了 JMS 重新连接策略的问题。我不确定我是否做对了(很可能我没有)。无论如何,我正在使用 WebLogic,这是一个消费者客户端。这是我获得连接并尝试添加自动重新连接的方法。问题是它没有重新连接,并且没有任何异常记录。我通过启动 weblogic 重新创建这种情况,启动获得初始连接的消费者客户端,我突然关闭 weblogic,然后我重新启动 weblogic,此时该消费者正在监听的队列中的任何消息都保留在队列中而不被确认因为他们没有收到。

public void setReceiver(MessageListener listener) {
        try {
            Properties parm = new Properties();
            parm.setProperty("java.naming.factory.initial",
                    "weblogic.jndi.WLInitialContextFactory");
            parm.setProperty("java.naming.provider.url", URL);
            parm.setProperty("java.naming.security.principal", username);
            parm.setProperty("java.naming.security.credentials", password);
            ctx = new InitialContext(parm);
            final QueueConnectionFactory connectionFactory = (QueueConnectionFactory) ctx
                    .lookup(conFactoryName);
            connection = connectionFactory.createQueueConnection();
            // TODO: 8/6/2012 Work on reconnection strategies for Consumer.
            ((WLConnection) connection)
                    .setReconnectPolicy(JMSConstants.RECONNECT_POLICY_ALL);
            ((WLConnection) connection).setReconnectBlockingMillis(30000L);
            ((WLConnection) connection).setTotalReconnectPeriodMillis(-1L);
            session = connection.createQueueSession(false,
                    Session.AUTO_ACKNOWLEDGE);

            queue = (Queue) ctx.lookup(queueName);
            // receiver = session.createReceiver(queue);
            // receiver.setMessageListener(listener);
            consumer = session.createConsumer(queue);
            consumer.setMessageListener(listener);

            connection.setExceptionListener(new ExceptionListener() {

                @Override
                public void onException(JMSException arg0) {
                    // Assume Disconnected.
                    FileHandler fh = null;
                    try {
                        fh = new FileHandler("./logs/ExceptionListener", true);
                    } catch (SecurityException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    SimpleFormatter formatter = new SimpleFormatter();
                    fh.setFormatter(formatter);
                    Logger log2 = Logger.getLogger("ExceptionListener");
                    log2.addHandler(fh);
                    boolean connected = false;
                    do {
                        if (connection != null) {
                            try {
                                connection.close();
                            } catch (JMSException e) {
                                log.warning(e.toString());
                            }
                            try {
                                connection = connectionFactory.createQueueConnection();
                                connection.setExceptionListener(this);
                                connection.start();
                                connected = true;
                            } catch (JMSException e) {
                                log.severe(e.toString());
                            }
                        }
                    } while (!connected);

                }
            });
            connection.start();

        } catch (JMSException je) {
            log.severe(je.getMessage());
        } catch (Exception e) {
            log.severe(e.getMessage());
        }
    }

最佳答案

所以我终于弄清楚了这个问题。未调用异常监听器的主要问题是由于我的构建路径中存在竞争 jar。我的构建路径中有 wlfullclient.jar、wljmsclient.jar 和 wlsasclient.jar 删除 wljmsclient.jar 和 wlsasclient.jar 后,我开始收到错误消息,这使我可以进一步调试。这是我的最终解决方案,它将尝试在初始连接时每 30 秒连接一次,然后如果它已获得连接但又失去连接,它将尝试每 30 秒重新连接一次:

public boolean setReceiver(MessageListener listener) {
        try {
            Properties parm = new Properties();
            parm.setProperty("java.naming.factory.initial",
                    "weblogic.jndi.WLInitialContextFactory");
            parm.setProperty("java.naming.provider.url", URL);
            parm.setProperty("java.naming.security.principal", username);
            parm.setProperty("java.naming.security.credentials", password);
            ctx = new InitialContext(parm);
            final QueueConnectionFactory connectionFactory = (QueueConnectionFactory) ctx
                    .lookup(conFactoryName);
            connection = connectionFactory.createQueueConnection();
            ((WLConnection) connection)
                    .setReconnectPolicy(JMSConstants.RECONNECT_POLICY_ALL);
            ((WLConnection) connection).setReconnectBlockingMillis(30000L);
            ((WLConnection) connection).setTotalReconnectPeriodMillis(-1L);
            session = connection.createQueueSession(false,
                    Session.AUTO_ACKNOWLEDGE);
            queue = (Queue) ctx.lookup(queueName);
            consumer = session.createConsumer(queue);
            consumer.setMessageListener(listener);

            connection.setExceptionListener(new ExceptionListener() {
                @Override
                public void onException(JMSException arg0) {
                    // Assume Disconnected.
                    Logger log2 = new MyLogger().getLogger("BPEL Client");
                    if (arg0 instanceof LostServerException) {
                        log2.severe("Connection to the Server has been lost, will retry in 30 seconds. "
                                + arg0.toString());
                    } else {
                        log2.severe(arg0.toString());
                    }

                }
            });
            connection.start();
            log.info("Successfully connected to " + URL);
            return true;
        } catch (JMSException je) {
            log.severe("Could not connect to the WebLogic Server, will retry in 30 seconds. "
                    + je.getMessage());
            try {
                Thread.sleep(30000L);
            } catch (InterruptedException e) {
                log.warning(e.toString());
            }
            return setReceiver(listener);
        } catch (Exception e) {
            log.severe("Could not connect to the WebLogic Server, will retry in 30 seconds. "
                    + e.toString());
            try {
                Thread.sleep(30000L);
            } catch (InterruptedException ie) {
                log.warning(ie.toString());
            }
            return setReceiver(listener);

        }
    }

关于java - 最初和已经获得先前连接后重新连接到 JMS 服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11833584/

相关文章:

java - 多个复合 Material 之间第一列的宽度相等

java - H2 内存 DB : Set Timezone with JDBC? Java 单元测试

java - 这个打开/关闭 JDBC 连接代码可以吗?

delphi - 是否有用于Delphi/Free Pascal的免费JMS客户端?

java - JMS 和 AMQP - RabbitMQ

java - 如何使 HTML 表格滚动

java - 从 Selenium 2.47.0 迁移到带有 FF 54 的 Selenium 3.13.0 后出现错误

iphone - sencha touch + phonegap::如何在 iOS iPhone 上测量互联网连接速度(3G 检查)

javascript - 如何在本地应用程序中连接前端(js)和后端(php)?

spring - Azure ServiceBus JMS 库是否支持托管标识?