ActiveMQ浏览器需要很长时间才能使用.hasMoreElements()

时间:2015-06-02 08:38:59

标签: java activemq

我尝试为ActiveMQ实现队列浏览器 下面显示的代码应显示名为' Q1'的队列中的文本消息。那里有两条消息。一般情况下它可以工作,但最后一次e.hasMoreElements()通话需要长达20秒。我想每500毫升更新一次清单。
为什么这么慢?
当我按“更新”时在http://localhost:8161/admin/browse.jsp?JMSDestination=Q1 e.hasMoreElements()的浏览器视图中立即返回。这里发生了什么?如何实现“实时”'查看?

        //init:
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");
        Connection connection = connectionFactory.createConnection();
        connection.start();
        Session session = connection.createSession(true, Session.CLIENT_ACKNOWLEDGE);
        Queue queue = session.createQueue("Q1");

        boolean run = true;
        while (run) {
            LOG.info("--------------------------------------------------------------------------------");
            QueueBrowser browser = session.createBrowser(queue);
            Enumeration e = browser.getEnumeration();
            while (e.hasMoreElements()) { //<- very slow before returning false after last message. why?
                Object o = e.nextElement();
                if (o instanceof ActiveMQTextMessage) {
                    LOG.info(((ActiveMQTextMessage) o).getText());
                } else {
                    LOG.info(o.toString());
                }
            }
            Thread.sleep(500);
            browser.close();
        }

        session.close();
        connection.close();

4 个答案:

答案 0 :(得分:0)

经过一番研究后,我尝试切换到更新的JMX技术。在队列中行走时没有性能问题。

一些代码:

25

您必须在配置中激活jmx。默认情况下它已取消激活。

答案 1 :(得分:0)

在我之前的评论之后,我发现在连接工厂上调用setTransactedIndividualAck(true)可以解决问题

ActiveMQConnectionFactory cf2 = new ActiveMQConnectionFactory(...);
cf2.setTransactedIndividualAck(true); 

我不确定这是解决这个问题的正确方法,但至少它现在有效。请在此处查看ActiveMQ用户论坛上的消息: http://activemq.2283324.n4.nabble.com/JMS-browser-getEnumeration-hasMoreElements-takes-15s-on-last-element-td4709969.html

答案 2 :(得分:0)

我有同样的问题。但是改变会话上的确认消除了延迟。

试试这个:

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

答案 3 :(得分:0)

我发现在Session.commit()循环中调用hasMoreElements()停止了使用activemq-broker版本5.14.5的挂起:

while(enumeration.hasMoreElements()) {
    final Message     message     = (Message)enumeration.nextElement();
    final TextMessage textMessage = (TextMessage)message;
    session.commit();
}

我进行了更多研究,以查看这是否是ActiveMQ的错误,并且发现activemq-broker版本5.15.1没有挂起,即使每次迭代后都没有调用commit()。经纪人的所有先前版本都挂在对hasMoreElements()的最终呼叫上。由于bug report on JIRA所引用的更改是出于不同的目的,因此似乎贡献者没有刻意解决此特定问题。 iterate()类的org.apache.activemq.broker.region.Queue方法的change that fixed this issue更改自:

// are we done browsing? no new messages paged
if (!added || browser.atMax()) {
    browser.decrementQueueRef();
    browserDispatches.remove(browserDispatch);
}

// are we done browsing? no new messages paged
if (!added || browser.atMax()) {
    browser.decrementQueueRef();
    browserDispatches.remove(browserDispatch);
} else {
    wakeup();
}

为确认这是解决此问题的更改,我使用了先前的版本5.15.0,并强制使用调试器调用wakeup(),而未调用hasMoreElements()挂。