2013-11-27 6 views
5

Я хочу создать инструмент, который сможет управлять сообщениями внутри очереди. Поэтому я хотел бы получить все сообщения из очереди (что-то вроде экспорта) и не удалять их оттуда.ActiveMQ получить все сообщения из очереди

Я пытался использовать 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); 
    } 

но messagesInQueue.hasMoreElements() всегда возвращает ложь, несмотря на очередь содержит много сообщений.

Также, если я пытаюсь использовать потребитель, он извлекает все сообщения, но удаляет их из очереди.

Я пытался экспортировать сообщения из очереди с помощью инструмента командной строки:

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

Но если очередь содержит около 1 млн сообщений он бросает

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

Итак, как я могу получить все сообщения формируют очереди и не удалять их оттуда?

+1

Когда сообщения не доставлены, возможно, вы должны сначала начать подключение. Вызовите connection.start() перед повторением сообщений из браузера или даже созданием объекта браузера. Спецификация JMS говорит о том, что перед употреблением сообщений требуется начало соединения, нет ни слова о том, как браузер должен работать, но поскольку просмотр не является таким обычным явлением, ActiveMQ реализовал его, вероятно, сам по себе. – Matej

+0

@Matej, спасибо, я забыл начать соединение. Когда я начал его, я мог читать около 5000 сообщений из очереди, но потом он долгое время останавливался при извлечении следующего элемента .... – evgeniy44

ответ

6

Браузер JMS Queue не гарантирует, что он вернет каждое сообщение в очереди. Он обеспечивает моментальный снимок сообщений, но может не дать их всем. В случае с ActiveMQ существуют ограничения на количество сообщений, которые он будет просматривать, чтобы уменьшить накладные расходы. Вы можете увеличить пределы, см. MaxBrowsePageSize, однако до сих пор нет способа гарантировать, что для очень глубокой очереди вы получите их все.

Лучшим вариантом будет использование маршрута Camel, который отправляет сообщения, нацеленные на некоторую очередь, в другую очередь процессов и зеркальную очередь, которую вы можете использовать с использованием стандартных JMS-пользователей или другого маршрута Camel. Таким образом, вы можете потреблять зеркальные сообщения в своем собственном темпе.

+1

зеркальные очереди - это хороший способ решить мою проблему, спасибо! – evgeniy44

0

messagesInQueue.hasMoreElements() всегда возвращает ложь becouse вы должны вызвать

connection.start(); 

перед тем итерацию очереди.

Смежные вопросы