DEV Community

Cover image for Hallo RabbitMQ - 2. Routing
Gabriel Weidmann
Gabriel Weidmann

Posted on

Hallo RabbitMQ - 2. Routing

Im nächsten Schritt geht es jetzt darum ein Gesamtkonzept für das aktuelle System zu finden. Dieses umfasst folgende Komponenten (abstrahiert):

  • Die UI-Applikation, über welche die Benutzer Daten anzeigen, erstellen, ändern und löschen können.
  • Eine Dokumenten-API, über welche Dokumente angelegt, gelöscht und bearbeitet werden können. Außerdem kann jedes Dokument 1-n Versionen enthalten
  • Ein Renderservice, der zu jeder Dokumentversion eine Vorschau rendert
  • Ein Backupservice, der die erste Version jedes Dokumentes nochmal extra wegspeichert
  • Ein Synchronisationsservice, der jede Dokumentänderung mit einem externen System synchronisiert

Aktuell unterteilen sich die Event-Producer und Consumer in folgende Gruppen:

Übersicht Producer und Consumer

Um diese Struktur umzusetzen, bietet RabbitMQ einige weitere Möglichkeiten an, um unsere Queues aus dem ersten Teil flexibler zu machen:

Routing

https://www.rabbitmq.com/tutorials/tutorial-four-dotnet.html

Für das Routing bietet RabbitMQ diverse Möglichkeiten an, um unsere Queues zu befüllen.

Direct exchange

Aus Teil 1 kennen wir ja bereits die Bindings mit dem RoutingKey. Direct exchange bedeutet also:

Finde alle Queues mit dem gleichen Key wie die Nachricht und schreibe sie dort hinein.

Beispiel Direct Exchange

Es dürfen natürlich auch mehrere Queues mit demselben BindingKey vorhanden sein:

Mehrere Queues mit gleichem BindingKey

Topic Exchange

Topic Exchange ist ähnlich zum Direct exchange, bietet aber die Möglichkeit mehrere Kriterien zu verwenden.

Ein Topic ist ein Textwert der 1 oder mehrere durch . getrennte Wörter, sowie ggf. Platzhalter enthält. Ohne Platzhalter verhält sich Topic Exchange exakt wie Direct Exchange.

Es gibt nur zwei Platzhalter:

  • * (Stern) steht für genau 1 beliebiges Wort
  • # (Raute) steht für 0 bis n Wörter

Wir könnten also z.B. die Konvention einführen, dass Binding Keys folgendes Format haben müssen:

<Kontext>.<Aktion>.

Es wäre in unserem Fall also möglich z.B. die Topic version.created, sowie document.* zu verwenden.

Beispiel Topic Binding Key

  • Alle Änderungen an einem Dokument gelangen immer an die UI, damit diese sich ggf. aktualisieren kann
  • Alle neuen Versionen gehen an die Render-Queue, damit eine neue Vorschau gerendert wird

Wichtig:

  • Der Binding Key muss trotzdem genau gematched werden, sonst gibt es keinen Treffer. document oder document.created.today wären somit von obigen Filtern nicht erkannt.
  • # als Filter matched alles

Umsetzungsmöglichkeit

Fügen wir jetzt die Teile mit den neuen Möglichkeiten zusammen, könnte sich folgendes Bild ergeben.

Topics

  • document
    • created
    • restored
    • deleted
    • metadata_changed
    • version.created
  • preview
    • created
    • failed

Beispiel-Architektur der Queues mit Topics

Beispielprojekt

Ich habe mal versucht das beispielhaft mit dem minimalen Setup umzusetzen. Das vollständige Projekt findet man hier: https://github.com/weidmanngabriel/rabbitmq_topics_poc

Man kann jetzt einfach auf der Kommandozeile eingeben welches Event die Dokument-API abschicken soll. Die Events verhalten sich dann so wie im obigen Bild definiert.


Mit diesem Wissen kommen wir schonmal ein ganzes Stück weiter. Im nächsten Teil können wir uns dann Details wie Sende- und Empfangsbestätigung, Callbacks, etc. ansehen.

Top comments (0)