我尝试为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();
答案 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()
挂。