2010-03-18 14 views
13

Ich verwende RabbitMQ unter RHEL 5.3 mit dem Java-Client. Ich habe 2 Knoten (Maschinen). Node1 verwendet Nachrichten aus einer Warteschlange auf Node2 mit der Java-Hilfsklasse QueueingConsumer.Kann mit RabbitMQ (Java-Client) festgestellt werden, ob die Netzwerkverbindung während des Verbrauchs geschlossen ist?

QueueingConsumer consumer = new QueueingConsumer(channel); 
channel.basicConsume("MyQueueOnNode2", noAck, consumer); 
while (true) 
{ 
    QueueingConsumer.Delivery delivery = consumer.nextDelivery(); 
    ... Process message - delivery.getBody() 
} 

Wenn die Schnittstelle nach unten auf Node1 oder Knoten 2 (zum Beispiel ifconfig eth1 nach unten) gebracht wird, der Client (oben) nie das Netz kennt, ist nicht mehr da. Bietet RabbitMQ eine Art von Konfiguration auf dem Java-Client, die verwendet werden kann, um festzustellen, ob die Verbindung verschwunden ist. Das Herunterfahren des RabbitMQ-Servers auf Node2 löst eine ShutdownSignalException aus, die abgefangen werden kann und die App in eine Reconnect-Schleife wechseln kann. Aber das Herunterfahren der Schnittstelle verursacht keine Art von Ausnahme, so dass der Code für immer auf consumer.nextDelivery() warten wird.

Ich habe auch versucht, die Timeout-Version dieses Anrufs zu verwenden. z.B.

QueueingConsumer consumer = new QueueingConsumer(channel); 
channel.basicConsume("MyQueueOnNode2", noAck, consumer); 
int timeout_ms = 30000; 
while (true) 
{ 
    QueueingConsumer.Delivery delivery = consumer.nextDelivery(timeout_ms); 
    if (delivery == null) 
    { 
     if (channel.isOpen() == false)    // Seems to always return true 
     { throw new ShutdownSignalException(); } 
    } 
    else 
    { 
    ... Process message - delivery.getBody() 
    } 
} 

aber scheint, dass dies immer wahr zurückgibt (obwohl die Schnittstelle inaktiv ist). Ich nehme an, die Registrierung für den ShutdownListener auf der Verbindung wird die gleichen Ergebnisse liefern, aber noch nicht ausprobiert.

Gibt es eine Möglichkeit, eine Art von Heartbeat zu konfigurieren, oder müssen Sie nur benutzerdefinierte Lease-Logik schreiben (z. B. "Ich bin jetzt hier"), um dies zum Laufen zu bringen?

Antwort

4

Im Allgemeinen sind Sie viel besser dran, Fragen zu Rabbitmq auf der Mailingliste Rabbitmq-Discussion zu stellen. Wir neigen nicht dazu, Fragen zu beantworten, die außerhalb davon gestellt werden.

Es gibt einen Heartbeat, den Sie konfigurieren können, obwohl er standardmäßig deaktiviert ist. Sie können TCP Keep Alive auch aktivieren. Entweder rufen setRequestedHeartbeat auf dem ConnectionFactory bevor eine neue Verbindung zu schaffen, oder Unterklasse ConnectionFactory, überschreiben die configureSocket Methode und socket.setKeepAlive(true) nennen. Beides sollte dazu führen, dass die Verbindung merkt, wenn das Netzwerk abstürzt.

3

Im Hinblick auf die isOpen Methode, das ist in der Dokumentation beschrieben: http://www.rabbitmq.com/api-guide.html#shutdown-atomicity

In Bezug auf die Herunterfahren: mit dem Herunterfahren node1 oder 2 Suchen Sie nach der Anwendung Recht, sich nicht dem RabbitMQ Server? Warum möchten Sie in einer Anwendung wissen, ob eine andere Anwendung die Verbindung zum Nachrichtenbroker unterbricht? Das ist nicht der Punkt der Nachrichtenübermittlung.

Das einzige, was Sie tun können, ist Nachrichten mit einem 'obligatorischen' Parameter zu senden. Das sagt der RabbitMQ Server, den Sie mindestens 1 Hörer für die Nachricht erwarten Sie gesendet haben (ob, dass eine direkte Warteschlange oder eine Warteschlange in einem Thema/Fanout-Austausch). Wenn die Nachricht dann nicht an eine Warteschlange gesendet werden kann, wird die Nachricht an Ihren Kanal zurückgegeben und an den angegebenen ReturnListener weitergeleitet.

Verwandte Themen