Mikroservices: Kommunikationsprotokolle und Tools
Mikroservices tauschen Nachrichten über zwei Hauptmodelle aus: synchron durch direkte HTTP-Anfragen an die Endpunkte eines anderen Services und asynchron über Broker wie Kafka oder RabbitMQ. Beim synchronen Modell wartet der Sender auf eine Antwort und kennt die URL sowie die Endpunkte des Empfängers. Das asynchrone Modell nutzt Topics, um Nachrichten ohne direkte Interaktion zu speichern.
Synchron eignet sich am besten für Anfrage-Antwort-Szenarien, während asynchron bei Events glänzt, wo zuverlässige Zustellung wichtiger ist als Geschwindigkeit.
Synchrone HTTP-Clients
Für direkte Aufrufe heben sich mehrere Tools ab:
- RestTemplate: Ein blockierender Client, der einfach ist, aber für neue Projekte veraltet, da er Threads blockiert.
- WebClient: Reaktiv auf Project Reactor, non-blocking, ideal für Systeme mit hohem Durchsatz und asynchroner Verarbeitung.
- Feign Client: Deklarativ – definiere eine Schnittstelle mit Annotationen, und Spring erzeugt die HTTP-Client-Implementierung. Synchron mit Caching-Unterstützung, reduziert Boilerplate-Code.
Feign macht es einfach: Annotiere eine Schnittstelle mit @GetMapping oder @PostMapping, und los geht's. WebClient übertrifft es beim Durchsatz dank non-blocking I/O.
Reaktive Programmierung mit WebClient
Reaktivität auf Project Reactor verwendet Mono (einzelner Wert) und Flux (Strom von Werten). Wichtige Unterschiede zur klassischen Asynchronität:
- Behandelt Datenströme über die Zeit mit Backpressure: Verbraucher signalisieren Produzenten, wenn sie bereit sind.
- Deklarative Operatoren wie map, filter, flatMap und buffer für Transformationen.
- Faule Auswertung: Operationen starten erst bei Subscription.
Beispiel zur Verarbeitung von Nutzern aus einem Repository:
Flux<User> users = userRepository.findAll();
Flux<String> names = users
.filter(u -> u.getAge() > 18)
.map(User::getName)
.take(10);
names.subscribe(name -> {
System.out.println("Received name: " + name);
});
Hier starten Datenbankabfragen erst bei .subscribe(). Reactor integriert sich nahtlos mit Spring WebFlux für reaktive Web-Apps. Nutze es bei hohen Lasten oder Streaming-Daten; für einfaches CRUD bleib bei synchronen Tools.
WebSocket für Event-gesteuerten Austausch
WebSocket schafft eine persistente Verbindung für bidirektionalen Event-Austausch ohne wiederholte Anfragen. Kein Anfrage-Antwort-Zyklus: Services pushen Nachrichten über den offenen Kanal.
Perfekt für:
- Chats und Echtzeit-Benachrichtigungen.
- Spiele und Börsenkurse mit Sofort-Updates.
- Zeitreihenströme ohne Polling.
Nachteil: Keine Zustellgarantien bei Verbindungsabbruch. Es geht um Geschwindigkeit, nicht um bombenfeste Zuverlässigkeit.
Kafka: Asynchroner Message Broker
Kafka ist ein verteiltes System zum Speichern und Streamen von Events. Produzenten senden an Topics (partitionierte Logs), Konsumenten lesen aus Partitionen.
Zustellgarantien:
- At-least-once: Nachrichten kommen mindestens einmal an (Duplikate möglich bei Commit-Fehlern).
- Exactly-once: Über idempotente Produzenten und Transaktionen.
Idempotenz sorgt dafür, dass wiederholte Anfragen dasselbe Ergebnis liefern. Broker-Replikation verhindert Datenverlust. Reihenfolge bleibt innerhalb von Partitionen durch Key erhalten (z. B. User-ID).
Konsumenten-Gruppen verteilen die Last: Mehrere Konsumenten bearbeiten Partitionen parallel.
Kafka-Einsatzgebiete:
- Asynchrone Events wie E-Mails, Analysen oder Boni.
- Replay der Historie für Neuberechnungen.
- Streaming (Kafka Streams, CDC aus Datenbanken).
Nachteile: Komplexe Cluster-Einrichtung (KRaft vereinfacht es gegenüber ZooKeeper), höhere Latenz als HTTP.
Wichtige Erkenntnisse
- Wähle Feign für einfache synchrone Aufrufe mit minimalem Code.
- Nutze WebClient für reaktive Systeme mit hoher Last und Flux/Mono.
- WebSocket für Echtzeit-Bidirektionalität ohne Zustellgarantien.
- Kafka für zuverlässige asynchrone Event-Kommunikation mit voller Historie.
- Kombiniere sie: Synchron für CRUD, asynchron für Events.
— Editorial Team
Noch keine Kommentare.