Playbook

CQRS (Command Query Responsibility Segregation) in Produktion: Konsistenz, Fehler und Wiederherstellung (CQRS In Produktion Konsistenz Fehler Und Wiederherstellung)

Wie bleibt CQRS in Produktion sicher? Consistency Lag, Duplicate Events, Reordering, Projection Recovery, Retries, DLQs und Saga-Strategien.

CQRS production recovery flow for retries, projections, and consistency

Wie diese Fehler für Nutzer aussehen

Wenn ein Bankguthaben zwei Sekunden verzögert ist, kann ein Nutzer denken, dass Geld verschwunden ist. Wenn ein Like-Zähler zwei Sekunden verzögert ist, akzeptieren es die meisten Nutzer vielleicht. Derselbe technische Lag erzeugt zwei unterschiedliche Produktrisiken.

Kommt dieselbe OrderPlaced Nachricht zweimal an, kann Inventory zweimal reduziert werden. Production-Konzepte sollten daher nicht nur als Definitionen, sondern über ihre Wirkung auf Nutzer und Geschäft gelesen werden.

Die eigentliche Frage in Produktion

Der Happy Path ist einfach: Ein Command wird akzeptiert, ein Event veröffentlicht und eine Projektion aktualisiert. In Produktion kommt eine Nachricht zweimal, ein Consumer fällt zurück, eine Projektion bricht oder ein Nutzer findet die gerade erstellte Bestellung nicht.

Command accepted → event published → projection delayed → user refreshes
"Ist meine Bestellung verschwunden?"

Partial Failure ist in verteilten Systemen keine Ausnahme. Dieses Kapitel entfernt Fehler nicht; es zeigt, wie Datenkorrektheit, Nutzervertrauen und Recovery Time beim Fehler erhalten bleiben.

Begriffe bei der ersten Verwendung

📦 Consistency Lag
Die Zeit zwischen erfolgreichem Write und aktualisiertem Read Model.

📦 Retry
Ein kontrolliertes Wiederholen nach einem vorübergehenden technischen Fehler.

📦 Dead-Letter Queue (DLQ)
Eine Queue für Nachrichten, die der normale Flow nicht verarbeiten kann.

📦 Checkpoint
Die letzte Event-Position, die eine Projektion sicher verarbeitet hat.

Eventual Consistency bedeutet nicht, dass Daten falsch sind. Unterschiedliche Modelle erreichen dieselbe Tatsache zu unterschiedlichen Zeiten. Ist das akzeptabel, muss das Produkt es klar erklären; ist es das nicht, braucht eine kritische Query eine andere Konsistenzstrategie.

Jede Verteidigung hat einen Grund

  • Ein Checkpoint wird gespeichert, weil ein Replay wissen muss, wo eine Projektion sicher fortsetzen kann.
  • Idempotenz ist nötig, weil ein Duplicate Event bei zweiter Anwendung reale Geschäftswirkung wie Inventory oder Payment beschädigt.
  • Retry wird begrenzt, weil eine fehlerhafte Nachricht durch Wiederholung nicht repariert wird, sondern Last und falsche Wirkung verstärken kann.
  • Eine DLQ wird genutzt, weil eine im normalen Flow ungelöste Nachricht sichtbaren Owner und Untersuchung braucht.
  • Der Partition Key ist die Aggregate ID, weil die kausale Reihenfolge eines Aggregates wichtiger ist als globale Event-Reihenfolge.
  • Wir machen Replay, weil verifizierte Event-Historie auch bei defekter Projektion die korrekte Quelle bleibt.

Consistency Lag ist eine Produktentscheidung

Wenn eine bezahlte Bestellung zwei Sekunden nicht in einer Liste erscheint, fühlt es sich wie Datenverlust an. Definieren Sie zuerst den sichtbaren Vertrag: Wie schnell muss jeder Screen nach einer Aktion aktuell sein?

POST /orders → 202 Accepted + orderId + version
GET /orders/{id}?minVersion=42
  → aktuelle Sicht, wenn Projektion 42 erreicht
  → Status "in Verarbeitung", solange sie es nicht hat

Optimistic UI, Polling oder Wait-for-Version können helfen. Sie entfernen Lag nicht, weil die eigentliche Aufgabe darin liegt, seine Bedeutung dem Nutzer ehrlich zu erklären. Das Ergebnis der Command Side bleibt die Quelle der Wahrheit für kritische Entscheidungen.

Duplicate Events und Reordering

At-least-once-Zustellung macht Duplicates normal. Ein Order Event zweimal zu verarbeiten kann Inventory zweimal reduzieren. Ein Consumer muss Event-ID und Aggregate-Version prüfen.

if event.id already processed: ignore
if event.version <= projection.version: ignore
apply event
store checkpoint and event id

Das ist ein O(1)-Lookup im Mittel oder ein O(log n)-B-Tree-Lookup. Wenn Reihenfolge nur in einer Partition garantiert ist, verwenden Sie Aggregate ID als Partition Key, weil die kausale Reihenfolge einer Bestellung wichtiger ist als globale Reihenfolge.

Retry, DLQ und der Entscheidungspunkt des Operators

Nicht jeder Fehler sollte wiederholt werden. Ein Network Timeout kann vorübergehend sein; ein ungültiges Event Schema ist dauerhaft.

Fehlertyp Reaktion Warum
Timeout / 503 Retry mit Exponential Backoff Eine Abhängigkeit kann sich erholen
Rate Limit Verzögerter Retry Erholung ohne Last zu verstärken
Schema Validation DLQ + Alarm Retry repariert die Nachricht nicht
Business Rule Failure Persistieren, prüfen, kompensieren Automatischer Retry kann falsche Wirkung verstärken

Eine DLQ ist kein Papierkorb. Jede Nachricht braucht Owner, Review-Fenster, Replay-Prozedur und Alarm.

Wie eine defekte Projektion wiederhergestellt wird

Eine Projektion ist kein Cache, sondern eine neu aufbaubare Geschäftssicht.

1. Consumer stoppen oder neue Projektionsversion erstellen
2. Letzten sicheren Checkpoint validieren
3. Event Stream kontrolliert erneut abspielen
4. Counts und Sample-Daten validieren
5. Traffic auf neue Projektion lenken
6. Lag und Error Rate beobachten

Replay-Kosten sind linear O(n) in der Event-Anzahl. Snapshots oder segmentiertes Replay können sie senken, aber ein Snapshot ist nicht Source of Truth. Weil Recovery auf verifizierter Event-Historie beruhen muss.

Der Fehlerpfad einer Saga

Wenn Payment im E-Commerce fehlschlägt, darf Inventory nicht dauerhaft reserviert bleiben. Eine Saga ist kein technischer Rollback; sie ist fachliche Kompensation.

Reserve inventory → Capture payment → Create shipment
                 payment fails → Release inventory

Auch Kompensation muss idempotent sein: ReleaseInventory zweimal auszuführen darf Inventory nicht zweimal erhöhen. Choreography bleibt für lokale Flows leicht; Orchestration gibt einem langen Workflow State Machine und einen Beobachtungspunkt.

Observability

Messen Sie Consumer Lag, Retry Count, DLQ Depth, Checkpoint Age, Duplicate Rate und End-to-End Action Time. Tragen Sie eine Trace ID vom Command über Event und Consumer bis zur Query.

Zuordnungen, die falsche Sicherheit schaffen

❌ Retry = Zuverlässigkeit
✓ Retry ist nur bei transienten Fehlern und idempotenter Arbeit sicher.

❌ DLQ = Recovery
✓ Eine DLQ startet einen Untersuchungs- und Replay-Prozess.

❌ Replay = immer sicher
✓ Ohne Versionierung und isolierte Side Effects kann Replay Wirkung wiederholen.

❌ Eventual Consistency = zufällige Verzögerung
✓ Lag muss gemessen, mit dem Produkt akzeptiert und Nutzern erklärt werden.

Production-Readiness-Check

  1. Gibt es ein Ziel für den nutzersichtbaren Consistency Lag?
  2. Ist jeder Consumer bei Duplicates und Out-of-Order Events sicher?
  3. Trennt Retry transiente und permanente Fehler?
  4. Hat jede DLQ-Nachricht Owner und Replay Runbook?
  5. Können Sie eine Projektion mit Produktionsdaten sicher neu aufbauen?
  6. Sind Saga-Kompensationen idempotent?

Wenn Sie jede Frage nicht mit Evidenz beantworten können, wirkt das System vielleicht skalierbar, ist aber noch nicht betreibbar.

Was sollte im Gedächtnis bleiben?

  1. Eventual Consistency ist ein über User Experience gesteuerter Vertrag.
  2. Duplicates und Reordering sind normale verteilte Zustellung, keine Edge Cases.
  3. Retry, DLQ und Replay sind ein Recovery-System.
  4. Eine nicht neu aufbaubare Projektion wird zu Operational Debt.
  5. Eine Saga rollt nicht zurück; sie kompensiert Geschäftswirkung.

Production Architecture zeigt sich nicht, wenn Nachrichten beim ersten Versuch richtig ankommen, sondern wenn sie doppelt, verspätet oder in unerwarteter Reihenfolge eintreffen.

FAQ

Häufige Fragen

Was ist Consistency Lag?

Die Zeit zwischen erfolgreichem Write und aktualisiertem Read Model.

Was ist Retry?

Ein kontrolliertes Wiederholen nach einem vorübergehenden technischen Fehler.

Stimmt es, dass „Retry = Zuverlässigkeit“?

Retry ist nur bei transienten Fehlern und idempotenter Arbeit sicher.

Was legt dieser Teil fest?

Partial Failure ist in verteilten Systemen keine Ausnahme. Dieses Kapitel entfernt Fehler nicht; es zeigt, wie Datenkorrektheit, Nutzervertrauen und Recovery Time beim Fehler erhalten bleiben. Eventual Consistency ist ein über User Experience gesteuerter Vertrag. Der Happy Path ist einfach: Ein Command wird akzeptiert, ein Event veröffentlicht und eine Projektion aktualisiert. In Produktion kommt eine Nachricht zweimal, ein Consumer fällt zurück, eine Projektion bricht oder ein Nutzer findet die gerade erstellte Bestellung nicht.

Gelernte Engineering-Prinzipien

  • Consistency Lag muss ein vom Produkt akzeptierter und für Nutzer sichtbarer Vertrag sein.
  • Idempotente Consumer sind für Duplicates, Reordering und Replay zwingend.
  • Recovery ist eine vorab entworfene Fähigkeit mit Checkpoints, Runbooks und Observability.

Weiterlesen

Weiterlesen

Verwandte Beitrage

Verwandte Beitrage

Verwandte Beitrage

Paylaş