Multiplexing RabbitMQ-Nachricht
Zum Beispiel habe ich 4 Quellen, die Metriken veröffentlichen. Ich möchte alle diese Nachrichten in einer Warteschlange / einem Austausch multiplexen / zusammenführen
--------+----+----+----+----+ -------+---------+----+---------+---------+
Source1 | M1 | M2 | M3 | | => Result | M1 | M4 | M2 | M3 | M6 | M5 | M7 |
Source2 | M4 | | | M5 |
Source3 | | | M6 | |
Source4 | | | | M7 |
For each queue:
* Read one message
* Publish message to the Result queue
Gibt es eine "native" Möglichkeit, dies in RabbitMQ zu tun, oder sollte ich meinen eigenen Consumer / Publisher schreiben?
BEARBEITEN 1
Ein Beispiel zur Verdeutlichung, sagen wir mal nach einiger Zeit
Processing "window"
+-+
Source1 |X|XXXXXXXXXXXXX
Source2 |Y|YYYYYYY
Source3 |Z|ZZZZZZZZZZ
Source4 |W|WW
+-+
Und dann später
Processing "window"
+-+
Source1 XXX|X|XXXXXXXXXX
Source2 YYY|Y|YYYY
Source3 ZZZ|Z|ZZZZZZZ
Source4 WWW| |
+-+
Und dann später
Processing "window"
+-+
Source1 XXXXXXXXX|X|XXXX
Source2 YYYYYYYY | |
Source3 ZZZZZZZZZ|Z|Z
Source4 WWW | |
+-+
Die ergebnisintensive Bestellung lautet: X Y Z W X Y Z W X Y Z W X Y Z X Y Z X Y Z X Y Z X Y Z X Z X Z X Z X X X
X, Y, Z, W dann X, Y, Z, W dann X, Y, Z, W dann X, Y, Z ... X, Z ...
Auf diese Weise können alle anderen Nachrichten aus anderen Quellen konsumiert werden, selbst wenn eine Quelle "spammt".
Aus technischen / finanziellen Gründen muss ich jeweils nur eine Nachricht konsumieren.
Der Verbraucher ist viel langsamer als die Produzenten, aber die Produzenten veröffentlichen viel, aber gelegentlich.
Wenn jede Quelle an einer Börse veröffentlicht wird, die an dieselbe Warteschlange gebunden ist, kann das Ergebnis XXXXXXXXXXXXXX YYYYYYYY ZZZZZZZZZZZ WWWoder sein XXXXX Y XXXXX YYY XXX YYYY ZZZZZZZZZZZ WWW(abhängig von der Veröffentlichungsrate jeder Quelle).
Antworten
Ich denke, was Sie wollen, können Sie einfach erreichen, indem Sie ein einziges Skript ausführen, das alle Warteschlangen abonniert.
Die Hauptanforderung besteht darin, einen einzelnen Anwendungsthread zu verwenden, um alle Nachrichten zu verarbeiten, unabhängig davon, aus welcher Warteschlange sie kommen. Was das aussieht wie auf variieren je nachdem , welche Sprache und Client - Bibliothek Sie verwenden - wenn Sie PHP verwenden, die Sie wirklich von Ihrem Weg zu gehen haben würde nicht Single-Thread zu sein, aber vielleicht gibt es einige Client - Bibliotheken sind Dies setzt voraus, dass sich jeder Rückruf in einem separaten Arbeitsthread befindet und Sie eine gemeinsam genutzte Ressource benötigen, damit sie blockiert werden können.
In Bezug auf die tatsächliche RabbitMQ-Seite der Dinge müssen Sie:
- Registrieren Sie ein Abonnement für den Server, um Nachrichten an Sie zu senden
basic.consume. Dies wird generell empfohlen, wennbasic.getohnehin explizit abgefragt wird - Verwenden Sie für alle
basic.consumeAnrufe einen einzigen "Kanal" - Verwenden Sie manuelle Bestätigungen, damit Nachrichten in der Warteschlange bleiben, bis Ihr Prozess abgeschlossen ist
- Legen Sie ein Prefetch-Limit pro Warteschlange von 1 mit fest
basic.qos
Wenn Sie 4 Warteschlangen haben, A, B, C und D, die beim Starten des Verbrauchers unterschiedlich viele Nachrichten enthalten:
- Wenn Sie sich zum ersten Mal anmelden, bedeutet das Prefetch-Limit, dass eine Nachricht aus jeder Warteschlange an den Kanal gesendet wird. Nennen Sie sie A1, B1, C1 und D1
- Die Clientbibliothek löst nacheinander für jedes dieser Ereignisse ein asynchrones Ereignis in Ihrer Anwendung aus
- Ihr einzelner Worker-Thread behandelt das erste dieser Ereignisse und beginnt mit der Verarbeitung der Nachricht A1
- Bis Sie diese Nachricht manuell bestätigen, können keine anderen Nachrichten eintreffen
- Sobald Sie die erste Nachricht (A1) bestätigt haben, kann eine neue Nachricht aus dieser Warteschlange (A2) vorab abgerufen werden.
- In der Zwischenzeit wird Ihr Worker-Thread das nächste Ereignis, das bereits ausgelöst wurde, für die Nachricht B1 entsperren und verarbeiten
- Erst wenn Sie die ausstehenden Ereignisse für B1, C1 und D1 verarbeitet haben, wird dem Worker-Thread das Ereignis für die Nachricht A2 angezeigt
- Solange in den Warteschlangen Nachrichten warten, werden diese im Round-Robin-Verfahren verarbeitet. Selbst wenn alle Warteschlangen bis auf eine leer werden, werden sie sofort nach Eingang einer Nachricht wieder in Rotation versetzt, da nur eine Nachricht aus der besetzten Warteschlange vorab abgerufen wurde. Der Rest wartet nur auf dem RabbitMQ-Server.