Microservices-Konsolidierung, die schiefging
Einen Monolithen aufzuteilen ist schwer. Microservices wieder zusammenzuführen? Schwerer — und in der Konsolidierungswelle von 2026 stehen deutlich mehr Teams kurz davor, das zu lernen.
Der Plan:
- 10 winzige Services, die verwandte Dinge tun
- Zusammenführen zu 3 Domain-Services
- Schätzung: 6 Wochen
Die Realität: 6 Monate.
Die Schätzung ging davon aus, dass Konsolidierung vor allem Code verschieben heißt. Tat sie nicht. Jede Servicegrenze hatte implizite Verträge angesammelt, die niemand aufgeschrieben hatte, und jeder davon kam erst zum Vorschein, als wir ihn löschen wollten.
Ein Beispiel, das drei Wochen kostete:
Zwei Services „besaßen“ beide die Kundenadresse. Profile hielt den normalisierten Datensatz; Shipping hielt eine denormalisierte Kopie, per Queue-Events mit ein paar Minuten Verzögerung aktualisiert. Der Merge-Plan sagte: Kopie löschen, aus der einen Tabelle lesen. Dann fanden wir einen nächtlichen Billing-Abgleichsjob, der absichtlich die Shipping-Kopie las — ihre eventgetriebene Verzögerung machte sie zu einem zufälligen Tagesend-Snapshot, und Rechnungen hingen davon ab, dass sich Adressen nicht mitten im Lauf änderten. Die Duplizierung war tragend. Sie zu entfernen hieß, einen expliziten Snapshot-Mechanismus zu entwerfen, den es nie gegeben hatte, für eine Anforderung, die nie dokumentiert worden war.
Was wir sonst noch entdeckten:
- Drei verschiedene Message-Queue-Muster — Fire-and-forget-Events, RPC über Queue mit Reply-Queues und verzögerte Nachrichten — jedes mit anderer Retry- und Idempotenz-Semantik, die In-Process-Aufrufe nicht nachbilden
- Service A erwartete JSON, wo Service B XML schickte, überdeckt von einem Übersetzungs-Shim, der niemandem gehörte
- Race Conditions, die erst auftraten, als zusammengeführter Code sich einen Prozess teilte und die implizite Serialisierung der Queue verlor
- Niemand hatte den vollständigen Abhängigkeitsgraphen — wir mussten ihn aus Traffic-Mitschnitten bauen
Was tatsächlich funktionierte: der Strangler Fig, nach innen gerichtet
Wir gaben den Big-Bang-Merge auf. Stattdessen stellten wir den Ziel-Domain-Service leer auf und verlagerten den Traffic über das API-Gateway Endpoint für Endpoint hinein: Lesezugriffe für eine Ressource zum neuen Service routen, im Shadow-Modus laufen lassen und die Antworten mit dem alten vergleichen, umschalten, wenn sie übereinstimmen, wiederholen. Jeder kleine Service wurde bis auf null Traffic stranguliert, bevor er stillgelegt wurde — dasselbe Muster wie beim Strangulieren eines Monolithen, nur dass die Fassade nach innen statt nach außen routet. Fortschritt wurde in Dashboards messbar, statt in Meetings versprochen.
Lektionen:
- Konsolidierung ist ein Rewrite, kein Refactoring — schätzen Sie sie auch so
- Dokumentieren Sie Service-Verträge obsessiv, inklusive Timing-Annahmen
- Pflegen Sie einen lebenden Abhängigkeitsgraphen, bevor Sie ihn brauchen
- Strangulieren Sie Services Endpoint für Endpoint heraus; nie den Merge als Big Bang
Wenn Sie diesen Weg abwägen, lesen Sie zuerst, wie die ursprüngliche Aufteilung typischerweise schiefgeht — den Monolithen zu schnell aufteilen —, denn schlechte Grenzen sind es, die den Rückweg teuer machen. Grenzarbeit in beide Richtungen ist der Punkt, an dem ein erfahrener DevOps- und Architekturpartner sein Geld verdient.
Lektion: Aufteilen ist (einigermaßen) umkehrbar. Die Kosten der Umkehr wachsen mit jedem Jahr, das die Grenze steht.
Incidents wie dieser sind vermeidbar. Unser AWS Managed Services-Team überwacht Kundenumgebungen 24/7 mit KI-gestütztem Monitoring und Senior Engineers am Pager — damit Geschichten wie diese im Archiv bleiben.