Enterprise Integration Patterns

Messaging-Grundlagen

Enterprise Integration Patterns · Gruppe 2 von 8

Lesestand

Diese Gruppe beschreibt die Grundbausteine jedes Messaging-Systems. Sie beantwortet die Fragen: Worüber werden Nachrichten verschickt? Wie sieht eine Nachricht aus? Wie wird sie unterwegs verarbeitet, weitergeleitet und übersetzt? Und wie kommt sie aus der Anwendung heraus und wieder hinein? Alle späteren Muster sind Spezialisierungen dieser sechs.

  • Anwendung
  • Integrationskomponente
  • Kanal
  • Nachricht
  • Datenbank / Speicher

5. Message Channel · Nachrichtenkanal

ShopKanal "neue-bestellungen"LagerShopKanal "stornierungen"LagerDer Shop kennt nur den Namen des Kanals, nicht den Empfänger
Zwei Kanäle für zwei Arten von Nachrichten. Wer am anderen Ende liest, weiß der Shop nicht.

Die Idee

Ein Kanal ist eine benannte Leitung im Messaging-System, über die Nachrichten von einem Sender zu einem Empfänger fließen. Der Sender schreibt in einen Kanal mit einem bestimmten Namen, der Empfänger liest aus einem Kanal mit diesem Namen. Direkt miteinander verbunden sind die beiden nie. Der Kanal ist ihre einzige gemeinsame Absprache.

Beispiel

Der Shop schreibt neue Bestellungen in den Kanal neue-bestellungen und Stornierungen in den Kanal stornierungen. Das Lager liest beide. Wird später ein zweites Lager angebunden oder das Lagersystem ausgetauscht, ändert sich am Shop nichts: Er schreibt weiter in dieselben Kanäle.

Worauf achten

Kanäle sind Teil der Architektur und werden meist bewusst geplant, nicht von jedem Programm spontan angelegt. Sinnvolle Namen und eine klare Regel, welche Art von Nachricht in welchen Kanal gehört, sind entscheidend. Ein Kanal für „alles Mögliche“ zwingt jeden Empfänger, erst herauszufinden, was er gerade bekommen hat. Wie viele Empfänger eine Nachricht erhält, regeln zwei Kanalarten aus Gruppe 3: Point-to-Point und Publish-Subscribe.

In der Praxis

Queues und Topics in JMS und RabbitMQ, Topics in Kafka, Queues in Amazon SQS. In Java ist das kleinste denkbare Modell eines Kanals eine BlockingQueue: Ein Thread legt hinein, ein anderer nimmt heraus.

6. Message · Nachricht

id: 7f3a-91c2 · zeit: 26.10.2026 13:39typ: Bestellung · antwort-an: bestaetigungen{ "kunde": "Sven","artikel": "4711", "menge": 2 }Headerfür das SystemBodyfür die AnwendungNachricht
Der Header enthält Verwaltungsdaten für das Messaging-System, der Body die eigentlichen Nutzdaten.

Die Idee

Daten werden nicht als loser Strom verschickt, sondern in einzelnen, abgeschlossenen Paketen. Jede Nachricht hat zwei Teile, wie ein Brief: den Header, also den Umschlag mit Verwaltungsangaben wie ID, Zeitstempel, Typ oder Antwortadresse, und den Body, den eigentlichen Inhalt. Das Messaging-System liest nur den Header, der Body ist für die Anwendungen bestimmt.

Beispiel

Eine Bestellung wird als Nachricht verschickt. Im Header stehen eine eindeutige ID, die Uhrzeit, der Typ „Bestellung“ und der Kanal, an den eine Bestätigung gehen soll. Im Body steht die Bestellung selbst als JSON. Ein Router kann anhand des Headers entscheiden, wohin die Nachricht geht, ohne den Inhalt verstehen zu müssen.

Worauf achten

Was in den Header und was in den Body gehört, ist eine wichtige Entscheidung: Technische Angaben, nach denen geroutet oder gefiltert wird, gehören in den Header. Fachliche Daten gehören in den Body. Nachrichten sollten außerdem klein bleiben. Große Datenmengen wie Bilder oder Dokumente verschickt man besser als Verweis (siehe Claim Check in Gruppe 6). Nach ihrem Zweck unterscheidet das Buch drei Arten, die Gruppe 4 genauer beschreibt: Command, Document und Event Message.

In der Praxis

jakarta.jms.Message mit Properties und Body, ProducerRecord in Kafka mit Headers, Key und Value, Message<T> in Spring Integration mit MessageHeaders und Payload. In Java 21 eignet sich ein record Nachricht(Map<String,String> header, T body) als einfaches Modell.

7. Pipes and Filters · Röhren und Filter

ShopEntschlüsselnPrüfenDuplikateentfernenFilter = ein VerarbeitungsschrittPipe = Kanal zwischen zwei Filternweiter
Jeder Filter erledigt genau einen Schritt und gibt das Ergebnis über einen Kanal an den nächsten weiter.

Die Idee

Eine komplexe Verarbeitung wird in eine Kette kleiner, unabhängiger Schritte zerlegt. Jeder Schritt, ein Filter, hat genau einen Eingang und einen Ausgang und erledigt genau eine Aufgabe. Die Filter sind über Kanäle verbunden, die Pipes. Kein Filter kennt seine Nachbarn. Er liest aus seinem Eingangskanal und schreibt in seinen Ausgangskanal.

Beispiel

Bestellungen kommen verschlüsselt an, sollen auf Vollständigkeit geprüft werden, und doppelt gesendete Bestellungen sollen entfernt werden. Statt einer großen Klasse, die alles erledigt, gibt es drei Filter. Soll später ein vierter Schritt hinzukommen, etwa das Ergänzen von Kundendaten, wird er einfach in die Kette gehängt.

Worauf achten

Der große Vorteil ist die Austauschbarkeit: Filter lassen sich einzeln testen, umsortieren, wiederverwenden und sogar mehrfach parallel betreiben, wenn ein Schritt zum Engpass wird. Der Preis ist Overhead: Jede Pipe bedeutet, dass eine Nachricht verschickt und wieder empfangen wird. Bei sehr vielen, sehr kleinen Schritten kostet das spürbar Zeit.

In der Praxis

Das Prinzip ist älter als Messaging: Die Unix-Shell verbindet Programme mit |, etwa cat log | grep FEHLER | sort | uniq. In Java folgen Streams demselben Gedanken, mit filter(), map() und distinct() als Filtern. Routen in Apache Camel und Flows in Spring Integration sind Pipes-and-Filters-Ketten über Nachrichtenkanäle.

8. Message Router · Nachrichtenverteiler

ShopRouterLagerDeutschlandLagerÖsterreichland = DEland = ATprüft und leitet weiter
Der Router liest jede Bestellung und schickt sie an das zuständige Lager. Der Shop weiß davon nichts.

Die Idee

Ein Router ist ein spezieller Filter mit einem Eingang und mehreren Ausgängen. Er liest jede Nachricht und entscheidet anhand einer Regel, in welchen Ausgangskanal sie gehört. Er verändert die Nachricht nicht, er bestimmt nur ihren Weg. Die Entscheidungslogik, wer wofür zuständig ist, steckt damit an einer Stelle statt beim Sender.

Beispiel

Der Shop schickt alle Bestellungen in einen Kanal. Ein Router prüft das Lieferland: Bestellungen nach Deutschland gehen an das Lager in Deutschland, Bestellungen nach Österreich an das Lager in Österreich. Kommt ein drittes Lager in der Schweiz hinzu, wird nur der Router angepasst. Shop und bestehende Lager bleiben unverändert.

Worauf achten

Ein Router darf nur entscheiden, nicht verarbeiten. Sobald er beginnt, Inhalte zu ändern oder Geschäftslogik auszuführen, wird er zum unübersichtlichen Zentralobjekt. Außerdem braucht jeder Router eine Antwort auf die Frage: Was passiert mit einer Nachricht, auf die keine Regel passt? Das Message Router-Muster ist der Oberbegriff für eine ganze Familie, die Gruppe 5 im Detail vorstellt, darunter Content-Based Router, Message Filter, Recipient List, Splitter und Aggregator.

In der Praxis

In Apache Camel choice().when(...), in Spring Integration @Router, in RabbitMQ Exchanges mit Routing Keys. Auch ein Mail-Server, der Post nach Empfängeradresse in Postfächer verteilt, ist ein Router.

9. Message Translator · Nachrichtenübersetzer

ShopTranslatorLager<order><qty>2</qty>XML, englische Felder{ "menge": 2 }JSON, deutsche Felderübersetzt Format, Feldnamen und Einheiten
Shop und Lager sprechen verschiedene Formate. Der Translator übersetzt dazwischen.

Die Idee

Verschiedene Systeme verwenden verschiedene Datenformate. Statt eines der Systeme umzubauen, setzt man einen Übersetzer dazwischen: einen Filter, der Nachrichten im Format A empfängt und im Format B weiterschickt. Er ist das Gegenstück zum Adapter-Muster der GoF, nur auf Ebene der Nachrichten statt der Objekte.

Beispiel

Der Shop stammt von einem internationalen Anbieter und verschickt Bestellungen als XML mit englischen Feldnamen. Das Lager erwartet JSON mit deutschen Feldnamen. Ein Translator wandelt <qty>2</qty> in "menge": 2 um. Keines der beiden Systeme muss sich ändern.

Worauf achten

Übersetzt wird oft auf mehreren Ebenen gleichzeitig: das Format (XML, JSON, CSV), die Struktur (verschachtelt oder flach), die Bedeutung (Feldnamen, Codes wie „DE“ gegen „Deutschland“, Einheiten wie Cent gegen Euro) und der Transport. Bei vielen Systemen droht eine Übersetzer-Explosion: Jedes Paar braucht einen eigenen. Dagegen hilft ein gemeinsames Zwischenformat, das Canonical Data Model aus Gruppe 6.

In der Praxis

XSLT für XML, Jackson und JSON-B für JSON in Java, MapStruct für Objekt-zu-Objekt-Abbildungen, in Camel transform() und marshal()/unmarshal(), in Spring Integration @Transformer.

10. Message Endpoint · Nachrichtenendpunkt

ShopGeschäftslogikkennt nur"Bestellung"EndpointEndpointLagerGeschäftslogikkennt den Broker, Verbindungen, FormateMessaging bleibt am Rand der Anwendung
Nur der Endpoint spricht mit dem Messaging-System. Die Geschäftslogik dahinter arbeitet mit normalen Objekten.

Die Idee

Eine Anwendung sollte nicht überall direkt mit der API des Messaging-Systems arbeiten. Stattdessen gibt es eine klar abgegrenzte Stelle, den Endpoint, die als einzige das Messaging kennt: Verbindungen aufbauen, Nachrichten erzeugen, senden, empfangen, Fehler behandeln. Die Geschäftslogik dahinter arbeitet mit ganz normalen Objekten und Methodenaufrufen.

Beispiel

Im Shop ruft die Bestelllogik nur bestellungen.senden(bestellung) auf. Der Endpoint dahinter wandelt das Objekt in JSON, setzt die Header, öffnet die Verbindung zum Broker und schickt die Nachricht. Wechselt das Unternehmen von RabbitMQ auf Kafka, wird nur der Endpoint ausgetauscht.

Worauf achten

Ein Endpoint ist entweder Sender oder Empfänger, aber nicht beides. Eine Anwendung, die sendet und empfängt, hat zwei Endpoints. Die genaue Ausgestaltung beschreibt das Buch in Gruppe 7: wie ein Empfänger an Nachrichten kommt (Polling oder Event-Driven Consumer), wie Endpunkte sich die Last teilen (Competing Consumers) oder wie das Messaging komplett hinter einer normalen Schnittstelle verschwindet (Messaging Gateway).

In der Praxis

Ein JmsTemplate oder KafkaTemplate in Spring zum Senden, eine Methode mit @JmsListener oder @KafkaListener zum Empfangen. Endpunkte in Apache Camel werden über URIs angesprochen, etwa from("jms:bestellungen").

Wie die sechs Bausteine zusammenspielen

ShopEPTranslatorRouterEPLagerEndpoint → Kanal → Translator → Kanal → Router → Kanal → EndpointRouter und Translator sind Filter, die Kanäle sind Pipes
Eine Bestellung auf dem Weg vom Shop zum Lager, mit allen Grundbausteinen dieser Gruppe.

Die sechs Muster dieser Gruppe sind die Grundbegriffe, aus denen alle weiteren zusammengesetzt sind. Eine Nachricht verlässt die Anwendung über einen Endpoint und fließt durch Kanäle. Unterwegs wird sie von Filtern bearbeitet, die nach dem Prinzip Pipes and Filters verkettet sind. Zwei Filterarten sind so wichtig, dass sie eigene Muster sind: der Router, der den Weg bestimmt, und der Translator, der das Format ändert. Die folgenden Gruppen verfeinern jeden dieser Bausteine.