DDD & Microservices
Microservices ohne DDD sind ein verteilter Monolith.
Domain-Driven Design definiert die richtigen Service-Grenzen. Event Sourcing und CQRS loesen Konsistenz- und Performanceprobleme. Ergebnis: Eine Architektur, in der Teams unabhaengig arbeiten.
Warum DDD vor Microservices¶
Die meisten gescheiterten Microservices-Architekturen teilen ein gemeinsames Problem: Services sind falsch aufgeteilt. Auth-Service, Notification-Service, User-Service — das sind technische Schichten, keine Geschaeftsdomaenen. Ergebnis: Ein verteilter Monolith, bei dem jede Aenderung die Koordination von 3 Teams erfordert.
DDD definiert Service-Grenzen nach Geschaeftsdomaenen. Bounded Context = Service. Ubiquitous Language = gemeinsames Vokabular zwischen Business und Tech-Teams. Ergebnis: Services, die sich unabhaengig aendern, weil sie unabhaengigen Geschaeftsbereichen entsprechen.
Event Storming — Discovery in 2-3 Tagen¶
Vor dem Code brauchen Sie eine Karte. Event Storming ist ein Workshop, bei dem Domaenenexperten und Entwickler gemeinsam Geschaeftsprozesse abbilden:
- Big Picture (halber Tag) — Alle Geschaeftsereignisse auf einer Zeitachse. Identifikation von Hotspots und Problemen.
- Process Modeling (1 Tag) — Detaillierter Ablauf fuer Schluesselprozesse. Commands, Events, Policies, Read Models.
- Software Design (1 Tag) — Aggregate, Bounded Contexts, Context Mapping. Technische Architektur aus dem Geschaeftsmodell.
Ergebnis: Eine Systemkarte, die sowohl CTO als auch Product Owner verstehen. Bounded Contexts bilden direkt auf Microservices ab.
Event Sourcing¶
Fuer Domaenen, die eine vollstaendige Historie erfordern (Finanzen, Audit, Compliance):
- Zustand = Summe der Ereignisse. Kein UPDATE, nur INSERT. Vollstaendige Rekonstruktion zu jedem Zeitpunkt.
- Audit-Trail kostenlos — Jede Aenderung ist ein Ereignis mit Kontext (wer, was, wann, warum).
- Temporale Abfragen — „Wie war der Kontostand am 31.12.2024?” Triviale Abfrage.
- Event Replay — Bugfix? Handler korrigieren, Events replaysn, Zustand wird korrigiert.
Wann KEIN Event Sourcing: CRUD-Domaenen, einfache Entitaeten ohne Geschaeftslogik, Daten mit hochfrequenten Aenderungen (IoT-Telemetrie). Event Sourcing fuegt Komplexitaet hinzu — wir verwenden es nur dort, wo es Mehrwert bringt.
CQRS — Trennung von Lesen und Schreiben¶
Command Query Responsibility Segregation:
- Write Model — Optimiert fuer Geschaeftslogik und Konsistenz. Aggregate, Invarianten, Validierung.
- Read Model — Optimiert fuer Abfragen. Denormalisierte Views, materialisierte Projektionen.
Beispiel: Bestellsystem. Write Model validiert Geschaeftsregeln (Bestand, Kredit, Limits). Read Model liefert denormalisierte Ansicht fuer Dashboard (Bestellung + Kunde + Produkte + Lieferstatus in einer Abfrage).
Anti-Patterns¶
- Geteilte Datenbank — Services teilen sich die Datenbank → enge Kopplung. Jeder Service hat seinen eigenen Store.
- Synchrone Ketten — A ruft B, B ruft C, C ruft D. Kaskadenausfall. Bevorzugen Sie asynchrone Events.
- Nano-Services — Zu kleine Services = mehr Netzwerkaufrufe, mehr Fehlerpunkte, mehr operativer Overhead.
- Gott-Service — Service, der alles weiss und alles tut. Refaktorieren zu Bounded Contexts.
- Verteilte Transaktionen — 2-Phase-Commit ueber Netzwerk. Verwenden Sie das Saga-Pattern.
Context Mapping¶
Beziehungen zwischen Bounded Contexts:
- Partnership — Zwei Teams arbeiten zusammen, gemeinsames Ziel
- Customer-Supplier — Upstream liefert, Downstream konsumiert
- Anti-Corruption Layer — Schutz vor fremdem Modell (typischerweise Legacy-Integration)
- Published Language — Gemeinsame Sprache fuer Integration (API-Vertraege)
Context Map ist ein lebendes Dokument — aktualisiert bei jeder Architekturanpassung.
Häufig gestellte Fragen
DDD ist sinnvoll fuer komplexe Domaenen mit umfangreicher Geschaeftslogik (Finanzen, Logistik, Versicherungen). Fuer CRUD-Anwendungen oder einfache APIs ist es uebertrieben. Wir entscheiden basierend auf einer Komplexitaetsbewertung.
Es gibt keine magische Zahl. Wir folgen Bounded Contexts aus dem Domaenenmodell. Typischerweise 5-15 Services fuer mittelkomplexe Systeme. Weniger ist mehr — Nano-Services bringen mehr Probleme als sie loesen.
Asynchron ueber Kafka (Events) fuer die meisten Faelle. Synchron ueber gRPC/REST fuer Abfragen, bei denen eine sofortige Antwort benoetigt wird. Regel: Befehle asynchron, Abfragen synchron.