JMS MessageConsumer使用MessageListener在ActiveMQ Shutdown上终止

时间:2014-08-29 02:39:52

标签: multithreading jms activemq failover message-listener

尝试使用JMS MessageConsumer在ActiveMQ重新启动后仍然存在,因此可以使用故障转移传输协议重新连接。

但是,它会在关闭ActiveMQ时终止。

这看起来像是一个被报告并且已经解决的错误"但我仍然在最新版本的ActiveMQ 5.10.0中看到这个

我使用了以下maven依赖

    <dependency>
        <groupId>org.apache.activemq</groupId>
        <artifactId>activemq-all</artifactId>
        <version>5.10.0</version>
    </dependency>

以下是一些使用

的示例代码
public class SimpleConsumer {

public static void main(String[] args) throws Exception {
    String url = "failover:(tcp://ACTIVE_MQ_HOST:61616)";
    String destination = "test-topic";

    TopicConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
            url);

    ActiveMQConnection connection = (ActiveMQConnection) connectionFactory
            .createConnection();

    Session session = connection.createSession(false,
            Session.AUTO_ACKNOWLEDGE);

    Topic topic = session.createTopic(destination);

    MessageConsumer consumer = session.createConsumer(topic);
    connection.start();

// Uncomment these lines and comment out the lines below and it will work
//      while (true) {
//          Message msg = consumer.receive();
//          if (msg instanceof TextMessage) {
//              System.out.println("msg received = " + msg);
//          }
//      }

    consumer.setMessageListener(new MessageListener() {

        public void onMessage(Message msg) {
            System.out.println("msg received = " + msg);
        }

    });

}

}

我希望它与MessageListener一起工作,它是非阻塞和异步的。

非常感谢任何帮助。

我已经按照上面报道的JIRA的建议尝试过的一些事情就是在非守护程序线程中运行它,但这并不起作用。

我试过这个

public class SimpleConsumerThread {

    public static void main(String[] args) throws Exception {


        Thread t = new Thread() {
            public void run() {
                try {               
                    String url = "failover:(tcp://ACTIVEMQ_HOST:61616)";
                    String destination = "test-topic";

                    TopicConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url);

                    ActiveMQConnection connection = (ActiveMQConnection) connectionFactory.createConnection();

                    Session session = connection.createSession(false,
                    Session.AUTO_ACKNOWLEDGE);

                    Topic topic = session.createTopic(destination);

                    MessageConsumer consumer = session.createConsumer(topic);
                    connection.start();
                    consumer.setMessageListener(new MessageListener() {

                        public void onMessage(Message msg) {
                            System.out.println("msg received = " + msg);
                        }

                    });
                } catch (JMSException e) {
                    e.printStackTrace();
                }               
            }
        };
        t.setDaemon(false);

        t.start();

    }

}

2 个答案:

答案 0 :(得分:1)

您的线程解决方案不起作用的原因是因为线程在run()方法完成后终止,然后您没有像以前一样运行非守护程序线程。依靠第三方库的内部线程模型来保持应用程序运行并不是一个好主意。

无论ActiveMQ客户端中的错误或其他配置错综复杂,最佳解决方案是使用while(true)sleep()范例来保持主线程的活动。

答案 1 :(得分:1)

谢谢Tim,

是的,有效。我刚刚补充说,要保持至少一个用户线程处于活动状态,以便程序不会终止。

    while(true) {
        Thread.sleep(1000);
    }

欢呼声,

public class SimpleConsumer {

    static Logger logger = Logger.getLogger(SimpleConsumer.class);

    public static void main(String[] args) throws Exception {
        String url = "failover:(tcp://sydapp057lx.fxdms.net:61615)";
        String destination = "test-topic";

        TopicConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
                url);

        ActiveMQConnection connection = (ActiveMQConnection) connectionFactory
                .createConnection();

        connection.setExceptionListener(new ExceptionListener() { 
            public void onException(JMSException e) {
                logger.debug("got exception = " + e);
            } 
        });

        Session session = connection.createSession(false,
                Session.AUTO_ACKNOWLEDGE);

        Topic topic = session.createTopic(destination);

        MessageConsumer consumer = session.createConsumer(topic);
        connection.start();

        consumer.setMessageListener(new MessageListener() {

            public void onMessage(Message msg) {
                logger.debug("msg received = " + msg);
            }

        });

        while(true) {
            Thread.sleep(1000);
        }

    }


}