Java ActiveMQ浏览器最后需要很长时间。hasMoreElements()

Java ActiveMQ浏览器最后需要很长时间。hasMoreElements(),java,activemq,Java,Activemq,我尝试为ActiveMQ实现队列浏览器。 下面显示的代码应显示名为“Q1”的队列中的文本消息。里面有两条信息。一般来说,它可以工作,但最后一次调用hasMoreElements()最多需要20秒。我想每500毫秒更新一次列表为什么这么慢?当我在浏览器视图中按“更新”以查看http://localhost:8161/admin/browse.jsp?JMSDestination=Q1e.hasMoreElements()立即返回。这是怎么回事?如何实现“实时”视图 //init:

我尝试为ActiveMQ实现队列浏览器。
下面显示的代码应显示名为“Q1”的队列中的文本消息。里面有两条信息。一般来说,它可以工作,但最后一次调用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();
//初始化:
ActiveMQConnectionFactory connectionFactory=新的ActiveMQConnectionFactory(“tcp://localhost:61616");
Connection=connectionFactory.createConnection();
connection.start();
Session Session=connection.createSession(true,Session.CLIENT\u确认);
Queue Queue=session.createQueue(“Q1”);
布尔运行=真;
while(运行){
LOG.info(“-----------------------------------------------------------------------------------------”;
QueueBrowser browser=会话.createBrowser(队列);
枚举e=browser.getEnumeration();

虽然(e.hasMoreElements()){/经过一些研究和尝试,我切换到了更先进的JMX技术。在遍历队列时没有性能问题

一些代码:

JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi");
JMXConnector connector = JMXConnectorFactory.connect(url, null);
connector.connect();
connection = connector.getMBeanServerConnection();
ObjectName name = new ObjectName(getObjectNameByBrokerName(brokerName));
brokerMBean = (BrokerViewMBean) MBeanServerInvocationHandler.newProxyInstance(connection, name, BrokerViewMBean.class, true);

ObjectName[] objNames = brokerMBean.getQueues();
for (ObjectName objName : objNames) {
    QueueViewMBean queueMBean = (QueueViewMBean) MBeanServerInvocationHandler.newProxyInstance(connection, objName, QueueViewMBean.class, true);
    System.out.println(queueMBean.getName());
}

您必须在配置中激活jmx。默认情况下,它是非激活的。

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

ActiveMQConnectionFactory cf2 = new ActiveMQConnectionFactory(...);
cf2.setTransactedIndividualAck(true); 
我不确定这是否是解决问题的正确方法,但至少它现在可以工作了。请参阅ActiveMQ用户论坛上的消息:

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

试试这个:

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

我发现在我的
hasMoreElements()
循环中调用
Session.commit()
,使用
activemq代理
version
5.14.5
停止了挂起:

while(枚举.hasMoreElements()){
最终消息消息=(消息)枚举.nextElement();
最终文本消息文本消息=(文本消息)消息;
commit();
}

我做了更多的研究,看看这是否是ActiveMQ的bug,发现
ActiveMQ代理
version
5.15.1
没有挂起,即使在每次迭代后没有调用
commit()
。代理的所有以前版本在最后调用
hasMoreElements()时都挂起
。参与者似乎并没有故意修复这个特定问题,因为他们发现引用的更改是用于不同的内容。类的
org.apache.activemq.broker.region.Queue的
iterate()
方法的更改部分来自:

//我们浏览完了吗?没有新消息分页
如果(!添加了| | browser.atMax()){
browser.decrementQueueRef();
browserDispatches.remove(browserDispatches);
}

//我们浏览完了吗?没有新消息分页
如果(!添加了| | browser.atMax()){
browser.decrementQueueRef();
browserDispatches.remove(browserDispatches);
}否则{
唤醒();
}

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

我与您的问题相同..您提出的解决方案做的事情不一样..您的第一个代码示例读取了Q中的所有消息。第二个列表是代理中定义的Q..我需要读取Q中的所有消息并获取最后一条消息可能需要15秒…我不知道为什么,也没有解决方案告诉你,我做不到。告诉你,这对我不起作用。