Ich fange gerade an, RabbitMQ und AMQP im Allgemeinen zu verwenden.
- Ich habe eine Warteschlange mit Nachrichten
- Ich habe mehrere Verbraucher, die ich mit derselben Nachricht verschiedene Dinge tun möchte .
Der größte Teil der RabbitMQ-Dokumentation scheint sich auf Round-Robin zu konzentrieren, dh wenn eine einzelne Nachricht von einem einzelnen Verbraucher konsumiert wird, wobei die Last auf jeden Verbraucher verteilt wird. Dies ist in der Tat das Verhalten, das ich sehe.
Ein Beispiel: Der Produzent hat eine einzelne Warteschlange und sendet alle 2 Sekunden Nachrichten:
var amqp = require('amqp');
var connection = amqp.createConnection({ host: "localhost", port: 5672 });
var count = 1;
connection.on('ready', function () {
var sendMessage = function(connection, queue_name, payload) {
var encoded_payload = JSON.stringify(payload);
connection.publish(queue_name, encoded_payload);
}
setInterval( function() {
var test_message = 'TEST '+count
sendMessage(connection, "my_queue_name", test_message)
count += 1;
}, 2000)
})
Und hier ist ein Verbraucher:
var amqp = require('amqp');
var connection = amqp.createConnection({ host: "localhost", port: 5672 });
connection.on('ready', function () {
connection.queue("my_queue_name", function(queue){
queue.bind('#');
queue.subscribe(function (message) {
var encoded_payload = unescape(message.data)
var payload = JSON.parse(encoded_payload)
console.log('Recieved a message:')
console.log(payload)
})
})
})
Wenn ich den Konsumenten zweimal starte, kann ich sehen, dass jeder Konsument alternative Nachrichten im Round-Robin-Verhalten konsumiert. ZB sehe ich die Nachrichten 1, 3, 5 in einem Terminal, 2, 4, 6 im anderen .
Meine Frage ist:
Kann ich jeden Verbraucher die gleichen Nachrichten empfangen lassen? Dh beide Verbraucher erhalten Nachricht 1, 2, 3, 4, 5, 6? Wie heißt das in AMQP / RabbitMQ? Wie ist es normalerweise konfiguriert?
Wird das allgemein gemacht? Sollte ich die Nachricht stattdessen nur durch den Austausch in zwei separate Warteschlangen mit einem einzigen Verbraucher weiterleiten lassen?
Antworten:
Kann ich jeden Verbraucher die gleichen Nachrichten empfangen lassen? Dh beide Verbraucher erhalten Nachricht 1, 2, 3, 4, 5, 6? Wie heißt das in AMQP / RabbitMQ? Wie ist es normalerweise konfiguriert?
Nein, nicht wenn sich die Verbraucher in derselben Warteschlange befinden. Aus dem AMQP Concepts Guide von RabbitMQ :
Dies scheint zu implizieren, dass das Round-Robin-Verhalten innerhalb einer Warteschlange gegeben und nicht konfigurierbar ist. Das heißt, separate Warteschlangen sind erforderlich, damit dieselbe Nachrichten-ID von mehreren Verbrauchern verarbeitet werden kann.
Wird das allgemein gemacht? Sollte ich die Nachricht stattdessen nur durch den Austausch in zwei separate Warteschlangen mit einem einzigen Verbraucher weiterleiten lassen?
Nein, es ist nicht so, dass eine einzelne Warteschlange / mehrere Verbraucher, bei denen jeder Verbraucher dieselbe Nachrichten-ID verarbeitet, nicht möglich sind. Es ist in der Tat besser, wenn der Austausch die Nachricht in zwei separate Warteschlangen weiterleitet.
Da ich kein zu komplexes Routing benötige, wird ein Fanout-Austausch dies gut handhaben. Ich habe mich früher nicht zu sehr auf den Austausch konzentriert, da node-amqp das Konzept eines "Standardaustauschs" hat, mit dem Sie Nachrichten direkt in einer Verbindung veröffentlichen können. Die meisten AMQP-Nachrichten werden jedoch in einem bestimmten Austausch veröffentlicht.
Hier ist mein Fanout-Austausch, sowohl beim Senden als auch beim Empfangen:
quelle
int prefetchCount = 1; channel.basicQos(prefetchCount);
Auf diese Weise kann jeder Verbraucher eine Nachricht erhalten, sobald die vorherige Nachricht fertig ist. Anstatt abwechselnde Nachrichten zu empfangen. Wiederum löst es Ihr Problem nicht, könnte aber nützlich sein, damit die Leute es wissen. Beispiel hier http://www.rabbitmq.com/tutorials/tutorial-two-java.html unter Fair DispatchLesen Sie einfach das rabbitmq-Tutorial . Sie veröffentlichen Nachrichten zum Austauschen und nicht zum Anstehen. Es wird dann an die entsprechenden Warteschlangen weitergeleitet. In Ihrem Fall sollten Sie für jeden Verbraucher eine separate Warteschlange binden. Auf diese Weise können sie Nachrichten völlig unabhängig voneinander konsumieren.
quelle
Die letzten paar Antworten sind fast richtig - ich habe Unmengen von Apps, die Nachrichten generieren, die bei verschiedenen Verbrauchern landen müssen, sodass der Vorgang sehr einfach ist.
Wenn Sie möchten, dass mehrere Verbraucher dieselbe Nachricht erhalten, gehen Sie wie folgt vor.
Erstellen Sie mehrere Warteschlangen, eine für jede App, die die Nachricht empfangen soll. Binden Sie in jeder Warteschlangeneigenschaft ein Routing-Tag an den amq.direct-Austausch. Ändern Sie Ihre Veröffentlichungs-App so, dass sie an amq.direct gesendet wird, und verwenden Sie das Routing-Tag (keine Warteschlange). AMQP kopiert dann die Nachricht mit derselben Bindung in jede Warteschlange. Klappt wunderbar :)
Beispiel: Nehmen wir an, ich habe eine JSON-Zeichenfolge, die ich generiere. Ich veröffentliche sie mit dem Routing-Tag "new-sales-order" an der Vermittlungsstelle "amq.direct". Ich habe eine Warteschlange für meine order_printer-App, die die Bestellung druckt. Ich habe eine Warteschlange für mein Abrechnungssystem, das eine Kopie der Bestellung sendet und dem Kunden eine Rechnung stellt. Ich habe ein Webarchivsystem, in dem ich Bestellungen aus historischen / Compliance-Gründen archiviere, und eine Weboberfläche des Kunden, in der Bestellungen nachverfolgt werden, wenn andere Informationen eingehen eine Bestellung.
Meine Warteschlangen sind also: order_printer, order_billing, order_archive und order_tracking. Alle haben das Bindungs-Tag "new-sales-order", alle 4 erhalten die JSON-Daten.
Dies ist eine ideale Möglichkeit, Daten zu senden, ohne dass die Veröffentlichungs-App die empfangenden Apps kennt oder sich darum kümmert.
quelle
Ja, jeder Verbraucher kann dieselben Nachrichten empfangen. Besuchen Sie http://www.rabbitmq.com/tutorials/tutorial-three-python.html http://www.rabbitmq.com/tutorials/tutorial-four-python.html http: //www.rabbitmq. com / tutorials / tutorial-five-python.html
für verschiedene Möglichkeiten zum Weiterleiten von Nachrichten. Ich weiß, dass sie für Python und Java sind, aber es ist gut, die Prinzipien zu verstehen, zu entscheiden, was Sie tun, und dann in JS zu finden, wie es geht. Es hört sich so an, als ob Sie ein einfaches Fanout ( Tutorial 3 ) durchführen möchten , das die Nachrichten an alle mit dem Austausch verbundenen Warteschlangen sendet.
Der Unterschied zu dem, was Sie tun und was Sie tun möchten, besteht im Wesentlichen darin, dass Sie Fanout einrichten und austauschen oder eingeben. Fanout-Excahnges senden alle Nachrichten an alle verbundenen Warteschlangen. Jede Warteschlange hat einen Verbraucher, der separat auf alle Nachrichten zugreifen kann.
Ja, dies wird üblicherweise durchgeführt. Dies ist eine der Funktionen von AMPQ.
quelle
Das Sendemuster ist eine Eins-zu-Eins-Beziehung. Wenn Sie an mehr als einen Empfänger "senden" möchten, sollten Sie das Pub / Sub-Muster verwenden. Weitere Informationen finden Sie unter http://www.rabbitmq.com/tutorials/tutorial-three-python.html .
quelle
RabbitMQ / AMQP: einzelne Warteschlange, mehrere Verbraucher für dieselbe Nachricht und Seitenaktualisierung.
quelle
Lassen Sie einfach jeden Verbraucher aus seiner eigenen Warteschlange konsumieren, um das gewünschte Verhalten zu erzielen. Sie müssen einen nicht direkten Austauschtyp (Thema, Header, Fanout) verwenden, um die Nachricht gleichzeitig an alle Warteschlangen zu senden.
quelle
Wie ich Ihren Fall einschätze, ist:
Ich habe eine Warteschlange mit Nachrichten (Ihre Quelle für den Empfang von Nachrichten, nennen wir sie q111)
Ich habe mehrere Verbraucher, die ich mit derselben Nachricht verschiedene Dinge tun möchte.
Ihr Problem hierbei ist, dass während 3 Nachrichten von dieser Warteschlange empfangen werden, Nachricht 1 von einem Verbraucher A verbraucht wird, andere Verbraucher B und C die Nachricht 2 und 3 verbrauchen. Wenn Sie ein Setup benötigen, bei dem rabbitmq dieselben Kopien von weiterleitet alle diese drei Nachrichten (1,2,3) an alle drei verbundenen Verbraucher (A, B, C) gleichzeitig.
Um dies zu erreichen, können viele Konfigurationen vorgenommen werden. Eine einfache Möglichkeit besteht darin, das folgende zweistufige Konzept zu verwenden:
Hinweis: Verwenden Sie dieses Konzept nicht direkt aus der Quellwarteschlange (q111), da bereits verbrauchte Nachrichten nicht an Ihren Fanout-Austausch gesendet werden.
Wenn Sie der Meinung sind, dass dies nicht Ihren genauen Anforderungen entspricht, können Sie gerne Ihre Vorschläge posten :-)
quelle
Wenn Sie die amqplib- Bibliothek wie ich verwenden, finden Sie hier ein praktisches Beispiel für eine Implementierung des RabbitMQ-Tutorials zum Veröffentlichen / Abonnieren, das Sie möglicherweise nützlich finden.
quelle
Ich denke, Sie sollten das Senden Ihrer Nachrichten mit dem Fan-Out- Austauscher überprüfen . Auf diese Weise erhalten Sie dieselbe Nachricht für verschiedene Verbraucher. Unter der Tabelle erstellt RabbitMQ für jeden dieser neuen Verbraucher / Abonnenten unterschiedliche Warteschlangen.
Dies ist der Link, um das Tutorial-Beispiel in Javascript https://www.rabbitmq.com/tutorials/tutorial-one-javascript.html zu sehen
quelle
In diesem Szenario gibt es eine interessante Option, die ich in den Antworten hier nicht gefunden habe.
Sie können Nachrichten mit der Funktion "Request" in einem Consumer nacken, um sie in einem anderen zu verarbeiten. Im Allgemeinen ist es kein richtiger Weg, aber vielleicht ist es gut genug für jemanden.
https://www.rabbitmq.com/nack.html
Und hüte dich vor Schleifen (wenn alle Verbraucher nackt sind + Nachricht anfordern)!
quelle