【问题标题】:ActiveMQ get all messages from the queueActiveMQ 从队列中获取所有消息
【发布时间】:2013-12-13 06:21:28
【问题描述】:

我想创建一些工具来管理队列中的消息。所以我希望能够从队列中获取所有消息(比如导出)并且不要从那里删除它。

我尝试使用 JMX API:

  ObjectName mbeanNameQueue = new ObjectName("org.apache.activemq:type=Broker,brokerName=static-broker1,destinationType=Queue,destinationName=tmp_queue2");
  org.apache.activemq.broker.jmx.QueueViewMBean queueView = JMX.newMBeanProxy(mbsc, mbeanNameQueue, org.apache.activemq.broker.jmx.QueueViewMBean.class);
  System.out.println(queueView.browseAsTable());

但我不能收到超过 400 条消息。

我也使用了这样的方法:

  ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:55901");
  ActiveMQConnection connection = (ActiveMQConnection)connectionFactory.createConnection();
  DestinationSource ds = connection.getDestinationSource();

  QueueSession queueSession = connection.createQueueSession(true, Session.CLIENT_ACKNOWLEDGE);
  Queue queue = queueSession.createQueue("tmp_queue2");
  QueueBrowser browser = queueSession.createBrowser(queue);
  Enumeration<?> messagesInQueue = browser.getEnumeration();

  while (messagesInQueue.hasMoreElements()) {
      Message queueMessage = (Message) messagesInQueue.nextElement();
      System.out.println(queueMessage);
  }

但messageInQueue.hasMoreElements() 总是返回false,尽管队列包含许多消息。

此外,如果我尝试使用消费者,它会检索所有消息,但会将其从队列中删除。

我尝试使用命令行工具从队列中导出消息:

activemq browse --amqurl tcp://localhost:55901 tmp_queue2  >> messages22222.txt

但是如果队列包含大约 1000000 条消息,它会抛出

Failed to execute main task. Reason: java.lang.OutOfMemoryError: GC overhead limit exceeded

那么,我怎样才能从队列中获取所有消息并且不从那里删除它们?

【问题讨论】:

  • 当没有消息传递时,也许你应该先启动连接。在从浏览器迭代消息甚至创建浏览器对象之前调用 connection.start()。 JMS 规范说在消费消息之前需要启动连接,没有关于浏览应该如何工作的消息,但是由于浏览不是那么常见的活动,ActiveMQ 可能已经自己实现了它。
  • @Matej,谢谢,我忘了开始连接。当我启动它时,我可以从队列中读取大约 5000 条消息,但随后它在检索下一个元素时停止了很长时间......

标签: java activemq jmx


【解决方案1】:

JMS 队列浏览器不保证它将返回队列中的每条消息。它提供消息的快照,但可能不会全部提供。在 ActiveMQ 的情况下,它会浏览多少消息以减少开销。您可以增加限制,请参阅 maxBrowsePageSize,但是仍然无法确保对于非常深的队列,您将获得所有限制。

更好的选择是使用 Camel 路由,该路由将针对某个队列的消息发送到另一个进程队列和一个镜像队列,您可以使用标准 JMS 消费者或另一个 Camel 路由将其排出。这样您就可以按照自己的节奏使用镜像消息。

【讨论】:

    【解决方案2】:

    messagesInQueue.hasMoreElements() 总是返回 false 因为你必须调用

    connection.start();
    

    在迭代队列之前。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-10-23
      • 2015-09-13
      • 1970-01-01
      • 2013-03-24
      • 2014-04-08
      • 2014-08-08
      • 1970-01-01
      相关资源
      最近更新 更多