2014-04-03 12 views
7
  1. DefaultConsumer
    Mein DemoConsumer erbt von DefaultConsumer.
    Ich habe festgestellt, dass auf diese Weise handleDelivery() von ThreadPool aufgerufen wird.
    (Druck Thread.currentThread(). GetName() Ich sehe Pool-1-Faden-1/2/3/4 eachtime.
    Ich habe auch mehrmals getestet und sah, dass der Auftrag gespeichert wird.
    Nur um sicherzustellen, dass - da verschiedene Threads Griff Lieferung nennen - wird es Chaos meine BestellungRabbitMQ Java-Client verwenden DefaultConsumer vs QueueingConsumer

  2. QueueingConsumer
    alle Java-Tutorial QueueingConsumer verwenden, um Nachrichten zu konsumieren
    In der API-Dokumentation es als deprecated Klasse erwähnt wird..
    Sollte ich meinen Code ändern, um von DefaultConsumer zu erben, verwenden Sie es? Ist das Tutorial veraltet?

Danke.

+0

Was meinst du mit "wird es meine Bestellung durcheinander bringen?" ? Bestellung von Fäden oder Nachrichten bestellen? – Gabriele

Antwort

12

Ja, DefaultConsumer verwendet einen internen Thread-Pool, der geändert werden kann. Mit ExecutorService als:

ExecutorService es = Executors.newFixedThreadPool(20); 
Connection conn = factory.newConnection(es); 

lesen http://www.rabbitmq.com/api-guide.html „Erweiterte Verbindungsoptionen“.

Wie Sie aus dem „QueueingConsumer“ lesen können doc:

Als solches ist es jetzt sicher Verbraucher direkt zu implementieren oder DefaultConsumer zu verlängern.

Ich habe nie QueueingConsumer verwendet, weil es nicht ereignisgesteuert ist.

Wie Sie hier sehen können:

QueueingConsumer consumer = new QueueingConsumer(channel); 
channel.basicConsume(QUEUE_NAME, true, consumer); 
while (true) { 
    QueueingConsumer.Delivery delivery = consumer.nextDelivery(); 
    /// here you are blocked, waiting the next message. 
    String message = new String(delivery.getBody()); 
} 

Ein typisches Problem in diesem Fall ist, wie das Abonnement zu schließen und eine gemeinsame Problemumgehung ist eine markierte schließen Nachricht in lokalen Host zu senden. Eigentlich mag ich es nicht so sehr.

Wenn Sie DefaultConsumer stattdessen erweitern, Sie richtig das Abonnement und den Kanal schließen können:

public class MyConsumer extends DefaultConsumer {...} 

dann

public static void main(String[] args) { 
MyConsumer consumer = new MyConsumer (channel); 
String consumerTag = channel.basicConsume(Constants.queue, false, consumer); 
System.out.println("press any key to terminate"); 
System.in.read(); 
channel.basicCancel(consumerTag); 
channel.close(); 
.... 

Abschließend sollten Sie nicht über die Nachricht, um Sorgen machen, weil, wenn alle funktioniert richtig, die Reihenfolge der Nachrichten ist korrekt, aber ich denke, Sie können es nicht annehmen, denn wenn es ein Problem gibt, können Sie die Reihenfolge der Nachrichten verlieren. Wenn Sie die Nachrichtenreihenfolge unbedingt einhalten müssen, sollten Sie ein sequenzielles Tag einfügen, um die Nachrichtenreihenfolge auf der Verbraucherseite zu rekonstruieren.

Und Sie sollten DefaultConsumer erweitern.

+0

Vielen Dank –

+0

Hallo, wie ein RateLimiter zu tun, wenn DefaultConsumer erweitert, da ich nicht steuern kann, ob eine Nachricht erhalten oder nicht, wenn DefaultConsumer erweitert, aber wenn QueueingConsumer verwendet, kann ich ablehnen vor consumer.nextDelivery() – chou

Verwandte Themen