ADR-0003: Kafka UND RabbitMQ - zwei Messaging-Systeme mit unterschiedlichem Zweck

Status

Akzeptiert (2026-08-04)

Kontext

Fuer asynchrone Kommunikation zwischen Services stehen grundsaetzlich zwei sehr unterschiedliche Kommunikationsmuster zur Debatte:

  1. Events ("etwas ist passiert", z. B. LoanCreated): potenziell interessant fuer mehrere, einander unbekannte Konsumenten; sollen wiederholt gelesen werden koennen (Replay, neue Konsumenten steigen spaeter ein); Reihenfolge pro Aggregat ist wichtig.
  2. Commands ("tu dies", z. B. SendNotificationCommand): hat genau einen fachlichen Empfaenger; soll genau einmal ausgefuehrt werden; nicht dafuer gedacht, dass ein neuer Konsument spaeter alte Commands nachverarbeitet.

Ein einzelnes Messaging-System fuer beide Faelle zu verwenden ist technisch moeglich (Kafka kann auch als Task-Queue missbraucht werden, RabbitMQ kann auch als Event-Log missbraucht werden), zwingt aber zu Kompromissen bei den jeweils dafuer nicht optimierten Eigenschaften.

Entscheidung

Wir verwenden beide Systeme, je nach Kommunikationsart (siehe common-events):

Kafka RabbitMQ
Verwendung Domain Events (IntegrationEvent) Commands (IntegrationCommand)
Zustellung Durables Log, 1:N, Consumer Groups Work Queue, 1:1 pro Nachricht ("competing consumers")
Replay Ja (Offset zuruecksetzen) Nein (Nachricht ist nach ACK weg)
Reihenfolge Pro Partition/Aggregat garantiert Pro Queue meist FIFO, aber kein Aggregat-Konzept
Fehlerbehandlung Konsument entscheidet (Retry, Skip, Dead-Letter-Topic) Native Dead-Letter-Queues, Retry-Policies
Beispiel-Topic/-Queue library.lending.loan-created library.notification.send-notification

notification-service fungiert dabei bewusst als Event-zu-Command-Uebersetzer: es konsumiert Kafka-Domain-Events und erzeugt daraus konkrete RabbitMQ-Commands (SendNotificationCommand) - ein haeufiges reales Muster, wenn "was ist passiert" von "was ist zu tun" entkoppelt werden soll.

Konsequenzen

Positiv

Negativ / Trade-offs

Alternativen erwogen

⌂ Cockpit