2013-11-27 14 views
5

Ich möchte ein Tool erstellen, das Nachrichten innerhalb der Warteschlange verwalten kann. Daher möchte ich alle Nachrichten aus der Warteschlange abrufen können (etwa Export) und sie nicht von dort entfernen.ActiveMQ alle Nachrichten aus der Warteschlange erhalten

Ich versuchte JMX API zu verwenden:

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()); 

Aber ich kann nicht mehr als 400 Meldungen erhalten.

Auch habe ich ein solcher Ansatz:

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); 
    } 

aber messagesInQueue.hasMoreElements() immer trotz der Warteschlange false zurückgibt enthält viele Nachrichten.

Auch wenn ich versuche, Consumer zu verwenden, ruft es alle Nachrichten ab, aber es entfernt es aus der Warteschlange.

Ich habe versucht, Nachrichten aus der Warteschlange zu exportieren mit Kommandozeilen-Tool:

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

Aber wenn Warteschlange enthält etwa eine Million Nachrichten, die es wirft

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

Also, wie kann ich alle Nachrichten bekommen bilden die Warteschlange und sie nicht von dort entfernen?

+1

Wenn keine Nachrichten zugestellt werden, sollten Sie die Verbindung möglicherweise zuerst herstellen. Rufen Sie connection.start() auf, bevor Sie die Nachrichten aus dem Browser iterieren oder sogar das Browserobjekt erstellen. Die JMS-Spezifikation besagt, dass ein Verbindungsstart erforderlich ist, bevor die Nachrichten konsumiert werden, kein Wort darüber, wie das Browsen funktionieren sollte, aber da das Browsen keine so häufige Aktivität ist, hat ActiveMQ es vermutlich selbst implementiert. – Matej

+0

@Matej, danke, ich habe vergessen, die Verbindung zu starten. Als ich anfing, konnte ich ungefähr 5000 Nachrichten aus der Warteschlange lesen, aber dann hörte es für eine lange Zeit beim Abrufen des nächsten Elements auf .... – evgeniy44

Antwort

6

Der JMS-Warteschlangen-Browser garantiert nicht, dass jede Nachricht in der Warteschlange zurückgegeben wird. Es bietet eine Momentaufnahme der Nachrichten, aber möglicherweise nicht alle. Im Fall von ActiveMQ gibt es Grenzen, wie viele Nachrichten es durchsuchen wird, um den Overhead zu reduzieren. Sie können die Limits erhöhen, siehe maxBrowsePageSize, aber es gibt immer noch keine Möglichkeit, sicherzustellen, dass Sie für eine sehr tiefe Queue alle erhalten.

Eine bessere Option wäre die Verwendung einer Camel-Route, die an eine Warteschlange gerichtete Nachrichten in eine andere Prozesswarteschlange und eine Spiegelwarteschlange sendet, die Sie mit Standard-JMS-Konsumenten oder einer anderen Camel-Route ablaufen lassen können. Auf diese Weise können Sie die gespiegelten Nachrichten in Ihrem eigenen Tempo konsumieren.

+1

Mirror Queues ist ein guter Weg, um mein Problem zu lösen, danke! – evgeniy44

0

messagesInQueue.hasMoreElements() gibt immer false becouse Sie

connection.start(); 

bevor die Warteschlange iterieren rufen müssen.

Verwandte Themen