- Authors

- Name
- Phillip Pham
- @ddppham
Monolith zu Microservices: Strangler Fig Pattern in der Praxis
TL;DR
- Das Strangler Fig Pattern erlaubt eine schrittweise Migration ohne Big-Bang-Release -- der Monolith bleibt aktiv, waehrend neue Services daneben laufen
- Ein Ingress Controller (oder API Gateway) routet Traffic dynamisch zwischen Monolith und neuen Microservices
- Datenmigration ist der schwierigste Teil: Dual-Write, Change Data Capture oder Event Sourcing sind die gaengigen Strategien
- Realistischer Zeitrahmen fuer die ersten 2-3 extrahierten Services: 3-4 Monate bei einem Team von 4-6 Personen
- Jeder Migrationsschritt muss reversibel sein -- ohne funktionierende Rollback-Strategie sollte man nicht starten
Warum das Strangler Fig Pattern?
Es gibt im Wesentlichen zwei Wege, einen Monolithen abzuloesen: Big-Bang-Rewrite oder inkrementelle Migration. Der Big-Bang-Rewrite scheitert in der Praxis fast immer. Joel Spolsky hat das 2000 bereits beschrieben, und die Erfahrung seitdem hat ihn bestaetigt.
Das Strangler Fig Pattern (benannt nach der Wuergfeige, die einen Wirtsbaum langsam umwaechst) funktioniert anders. Der Monolith bleibt laufen. Neue Features werden als Microservices gebaut. Bestehende Module werden Stueck fuer Stueck extrahiert. Ein Proxy-Layer entscheidet, welche Requests wohin gehen.
Der entscheidende Vorteil: Zu jedem Zeitpunkt haben Sie ein funktionierendes System. Wenn ein neuer Service Probleme macht, leiten Sie den Traffic zurueck auf den Monolithen. Kein Risiko eines kompletten Ausfalls.
Voraussetzungen pruefen
Bevor Sie starten, brauchen Sie Klarheit ueber drei Dinge:
1. Domainanalyse: Welche Bounded Contexts existieren in Ihrem Monolithen? Ohne ein grundlegendes Domain-Modell werden Sie die falschen Schnitte machen und mit verteiltem Monolithen enden -- das Schlimmste aus beiden Welten.
2. Teamstruktur: Microservices funktionieren nur mit autonomen Teams, die End-to-End-Verantwortung uebernehmen. Wenn Ihre Organisation das nicht unterstuetzt, wird die Migration scheitern -- nicht an der Technik, sondern an der Kommunikation.
3. Betriebsreife: Sie brauchen CI/CD-Pipelines, Container Registry, Monitoring und Logging, bevor der erste Microservice in Produktion geht. Ohne Observability betreiben Sie keine Microservices, sondern verteiltes Chaos.
Architektur: Ingress-basiertes Routing
Das Herzstuck des Strangler Fig Pattern ist ein Routing-Layer, der entscheidet, ob ein Request zum Monolithen oder zu einem Microservice geht. In Kubernetes uebernimmt das ein Ingress Controller.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: strangler-routing
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
ingressClassName: nginx
rules:
- host: api.example.com
http:
paths:
# Bereits migrierte Endpunkte -> neuer Service
- path: /api/orders(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: order-service
port:
number: 8080
# Alles andere -> Monolith
- path: /api(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: monolith
port:
number: 8080
Die Reihenfolge der Pfade ist entscheidend. Spezifischere Pfade (z.B. /api/orders) muessen vor dem Catch-all (/api) stehen. So koennen Sie Endpunkt fuer Endpunkt migrieren, ohne dass Clients etwas aendern muessen.
Fuer komplexeres Routing (z.B. Header-basiert, gewichtete Verteilung fuer Canary Deployments) lohnt sich ein Blick auf Istio oder Linkerd als Service Mesh. Mehr dazu im Artikel zu Canary Deployments.
Datenstrategie: Der schwierige Teil
Die Extraktion von Code ist vergleichsweise einfach. Die Frage "Wem gehoeren welche Daten?" ist der eigentliche Knackpunkt. Es gibt drei gaengige Strategien:
| Strategie | Vorteil | Nachteil | Wann sinnvoll |
|---|---|---|---|
| Shared Database | Minimaler Aufwand | Kopplung bleibt, Schema-Aenderungen sind gefaehrlich | Nur als Uebergangsloesung |
| Dual-Write | Schrittweise Trennung | Konsistenzprobleme, erhoehte Komplexitaet | Wenn CDC nicht moeglich ist |
| Change Data Capture | Saubere Entkopplung | Erfordert Infrastruktur (Debezium, Kafka) | Bevorzugte Loesung |
Fuer die meisten Teams empfehle ich, mit einer Shared Database zu starten und dann ueber Change Data Capture (CDC) auf getrennte Datenbanken zu migrieren. Debezium auf Kafka Connect ist hier der De-facto-Standard.
# Debezium Connector fuer PostgreSQL registrieren
curl -X POST http://kafka-connect:8083/connectors -H "Content-Type: application/json" -d '{
"name": "monolith-db-connector",
"config": {
"connector.class": "io.debezium.connector.postgresql.PostgresConnector",
"database.hostname": "monolith-db",
"database.port": "5432",
"database.user": "debezium",
"database.password": "${file:/secrets/db-password.txt:password}",
"database.dbname": "monolith",
"database.server.name": "monolith",
"schema.include.list": "orders",
"plugin.name": "pgoutput",
"publication.name": "orders_publication",
"slot.name": "orders_slot",
"topic.prefix": "cdc"
}
}'
Damit streamt Debezium jede Aenderung an der orders-Tabelle als Event auf Kafka. Der neue Order-Service konsumiert diese Events und baut seine eigene Datenbank auf. Sobald die Datenmigration abgeschlossen ist, trennen Sie die Verbindung zum Monolithen.
Extraktionsreihenfolge bestimmen
Nicht jedes Modul eignet sich gleich gut als erster Microservice. Bewerten Sie Kandidaten anhand dieser Kriterien:
| Kriterium | Gewicht | Beschreibung |
|---|---|---|
| Wenige Abhaengigkeiten | Hoch | Module mit vielen eingehenden Aufrufen sind schwer zu extrahieren |
| Klare Domaengrenze | Hoch | Wenn Sie die API-Grenze nicht klar definieren koennen, ist es zu frueh |
| Hohe Aenderungsfrequenz | Mittel | Module, die oft geaendert werden, profitieren am meisten |
| Eigenes Datenmodell | Mittel | Geteilte Tabellen erhoehen die Komplexitaet enorm |
| Team-Ownership moeglich | Hoch | Ein Service ohne klares Team wird zur Waise |
Typische Kandidaten fuer den Anfang: Benachrichtigungsservices, Reporting-Module, oder eigenstaendige Geschaeftsprozesse wie Rechnungsstellung.
Rollback-Strategie
Jeder Migrationsschritt braucht einen getesteten Rollback-Pfad. In der Praxis bedeutet das:
Traffic-Rollback: Aendern Sie das Ingress-Routing, sodass betroffene Pfade wieder zum Monolithen zeigen. Das ist in Sekunden erledigt und sollte automatisiert sein.
Daten-Rollback: Hier wird es komplizierter. Solange Sie im Dual-Write-Modus sind, hat der Monolith noch aktuelle Daten. Nach vollstaendiger Datentrennung brauchen Sie einen Mechanismus, um Daten zurueck zu synchronisieren.
# Terraform-Konfiguration fuer Feature-Flag-gesteuerten Rollback
# (Beispiel mit ConfigMap als einfacher Feature Toggle)
apiVersion: v1
kind: ConfigMap
metadata:
name: migration-flags
namespace: production
data:
ORDER_SERVICE_ENABLED: "true"
ORDER_SERVICE_ROLLBACK_THRESHOLD_MS: "2000"
ORDER_SERVICE_CIRCUIT_BREAKER_ENABLED: "true"
ORDER_SERVICE_FALLBACK_TO_MONOLITH: "false"
Nutzen Sie Feature Flags in Kombination mit einem Circuit Breaker. Wenn der neue Order-Service langsamer als der definierte Schwellwert antwortet, faellt das System automatisch auf den Monolithen zurueck. Mehr zu Rollback-Strategien in unserem Artikel zu Rollback-Strategien in Kubernetes.
Realistischer Zeitplan
Vergessen Sie Zeitplaene, die eine vollstaendige Migration in 120 Tagen versprechen. Eine ehrliche Einschaetzung:
Monat 1-2: Plattform aufbauen (Kubernetes-Cluster, CI/CD, Monitoring, Logging). Domainanalyse durchfuehren. Ersten Service-Kandidaten identifizieren.
Monat 3-4: Ersten Microservice extrahieren und in Produktion bringen. Ingress-Routing konfigurieren. Parallelbetrieb mit dem Monolithen.
Monat 5-8: Zweiten und dritten Service extrahieren. Datenmigration fuer den ersten Service abschliessen. Prozesse verfeinern.
Monat 9+: Fortlaufende Migration. Ab hier beschleunigt sich der Prozess, weil Infrastruktur und Prozesse stehen.
Die vollstaendige Abloesung eines gewachsenen Monolithen dauert je nach Groesse 1-3 Jahre. Wer etwas anderes behauptet, hat es noch nie gemacht.
CI/CD fuer den Parallelbetrieb
Waehrend der Migration betreiben Sie zwei Systeme parallel: den Monolithen und die neuen Microservices. Ihre CI/CD-Pipeline muss beides abdecken.
Fuer die neuen Microservices empfehle ich von Anfang an eine GitOps-basierte Pipeline. Jeder Service hat sein eigenes Repository (oder Verzeichnis in einem Mono-Repo) mit eigenem Deployment-Manifest. ArgoCD oder Flux synchronisieren den gewuenschten Zustand aus Git mit dem Cluster.
Fuer den Monolithen aendert sich erstmal wenig. Er wird weiterhin ueber den bestehenden Deployment-Prozess ausgerollt. Wichtig ist nur, dass Sie die API-Kompatibilitaet zwischen Monolith und Microservices in der Pipeline testen. Contract Tests (z.B. mit Pact) verhindern, dass ein Monolith-Update eine Schnittstelle bricht, die ein Microservice benoetigt.
Ein konkreter Pipeline-Aufbau fuer einen extrahierten Service koennte so aussehen:
- Code pushen auf den Feature-Branch
- Unit Tests + Integration Tests laufen in der CI
- Container Image bauen und in die Registry pushen
- ArgoCD erkennt das neue Image und deployt auf Staging
- Smoke Tests gegen Staging (inkl. Kommunikation zum Monolithen)
- Manuelles Approval fuer Produktion
- ArgoCD deployt auf Produktion, Traffic-Shift ueber Ingress
Dieser Ablauf stellt sicher, dass kein neuer Service in Produktion geht, ohne gegen den Monolithen getestet worden zu sein.
Monitoring: Was Sie messen muessen
Ohne Observability wissen Sie nicht, ob die Migration funktioniert. Diese Metriken sind Pflicht:
| Metrik | Warum | Tool |
|---|---|---|
| Request Latency (p50, p95, p99) | Erkennen, ob der neue Service langsamer ist | Prometheus + Grafana |
| Error Rate pro Endpunkt | Regressionen sofort sehen | Prometheus Alertmanager |
| Traffic-Split-Ratio | Wie viel Traffic geht wohin | Ingress Metriken |
| Daten-Konsistenz | Vergleich Monolith vs. Microservice DB | Custom Reconciliation Job |
Investieren Sie frueh in Distributed Tracing (Jaeger oder Tempo). Ohne Traces sind Debugging-Sessions in verteilten Systemen ein Albtraum. Mehr dazu im Artikel zum Observability Stack.
Organisatorische Voraussetzungen
Technisch ist die Migration machbar. In der Praxis scheitern die meisten Projekte an organisatorischen Problemen. Drei Dinge muessen stimmen:
Team-Topologie: Jeder Microservice braucht ein Team, das ihn besitzt -- Entwicklung, Betrieb, on-call. Wenn Sie 15 Services bauen, aber nur 2 Ops-Leute haben, wird das nicht funktionieren. Conway's Law gilt: Die Architektur Ihrer Software wird Ihre Organisationsstruktur widerspiegeln.
Entscheidungsfreiheit: Teams muessen Technologieentscheidungen innerhalb ihres Services selbst treffen koennen. Wenn jede Bibliotheksversion durch ein zentrales Architecture Board genehmigt werden muss, verlieren Sie den Geschwindigkeitsvorteil von Microservices.
On-Call-Kultur: Wer den Service baut, betreibt ihn auch. "You build it, you run it" ist keine nette Idee, sondern eine Notwendigkeit. Ohne diese Kultur enden Sie mit einem Ops-Team, das 30 Services betreut, die es nicht versteht.
Wenn Ihre Organisation diese Voraussetzungen nicht erfuellt, sollten Sie erst die Organisation aendern, bevor Sie die Architektur aendern. Eine Microservices-Architektur in einer Silo-Organisation ist schlimmer als ein gut gepflegter Monolith.
Haeufige Fehler
Distributed Monolith: Sie haben Microservices gebaut, aber jeder Service ruft synchron drei andere auf. Das ist kein Fortschritt, sondern ein Rueckschritt. Setzen Sie auf asynchrone Kommunikation ueber Events, wo immer moeglich.
Zu fruehe Optimierung: Starten Sie nicht mit Service Mesh, Event Sourcing und CQRS gleichzeitig. Fuegen Sie Komplexitaet hinzu, wenn Sie sie brauchen -- nicht vorher.
Fehlende Teamautonomie: Wenn jedes Deployment durch drei Genehmigungsprozesse muss, verlieren Sie den Hauptvorteil von Microservices. Teams muessen unabhaengig deployen koennen.
Kein Investment in Developer Experience: Wenn das Aufsetzen einer lokalen Entwicklungsumgebung einen halben Tag dauert, wird niemand gerne an Microservices arbeiten. Tools wie Tilt oder Telepresence helfen.
Fehlende Datenstrategie: Der haeufigste technische Fehler: Services teilen sich eine Datenbank, und niemand plant die Trennung. Nach sechs Monaten hat man zehn Services, die alle auf dieselbe PostgreSQL-Instanz zugreifen, mit Cross-Service-Joins in der Applikationslogik. Das ist schwerer zu entkoppeln als der urspruengliche Monolith.
Zu viele Services auf einmal: Drei Services gleichzeitig zu extrahieren klingt nach Effizienz, fuehrt aber zu einem Koordinations-Alptraum. Extrahieren Sie einen Service, bringen Sie ihn in Produktion, lernen Sie aus den Fehlern, und erst dann den naechsten. Mehr zu Feature Flags und schrittweisen Rollouts im Artikel zu Feature Flags.
Wann sollten Sie NICHT migrieren?
Nicht jeder Monolith muss zerlegt werden. Es gibt Situationen, in denen eine Migration mehr schadet als nuetzt:
- Ihr Monolith funktioniert gut und Ihr Team kann Features schnell genug liefern
- Sie haben weniger als 5 Entwickler -- der Overhead von Microservices lohnt sich nicht
- Die Domaene ist nicht klar genug, um sinnvolle Service-Grenzen zu ziehen
- Sie haben kein Team, das Kubernetes und verteilte Systeme betreiben kann
Ein gut strukturierter Monolith (modularer Monolith) ist besser als schlecht geschnittene Microservices. Wenn Sie sich unsicher sind, starten Sie mit einem modularen Monolithen und extrahieren Sie Services erst, wenn Sie die Domaene gut genug verstehen.
Zusammenfassung
Die Migration vom Monolithen zu Microservices ist kein Technologie-Problem, sondern ein Organisations-Problem. Das Strangler Fig Pattern gibt Ihnen einen sicheren Rahmen fuer die technische Umsetzung. Aber ohne klare Domaengrenzen, autonome Teams und solide Betriebsprozesse wird auch das beste Pattern nicht helfen.
Starten Sie klein, messen Sie alles, und akzeptieren Sie, dass es ein Marathon ist -- kein Sprint.
Weitere relevante Artikel:
- Hosting-Kosten: Cloud vs. On-Premise im Vergleich
- Capacity Planning fuer Kubernetes-Cluster
- CI/CD Pipelines im Enterprise-Umfeld
Falls Sie Unterstuetzung bei der Planung oder Umsetzung Ihrer Migration benoetigen, melden Sie sich gerne fuer ein unverbindliches Gespraech unter /kontakt.
Kubernetes-Beratung gesucht?
Wir helfen deutschen Unternehmen bei der Kubernetes-Implementierung, Migration und Optimierung. DSGVO-konform und praxiserprobt.
📖 Verwandte Artikel
Weitere interessante Beiträge zu ähnlichen Themen
Microservices Decomposition: Monolith aufteilen
Monolith in Microservices aufteilen mit Domain-Driven Design und Strangler Fig Pattern. Praktischer Kubernetes-Guide mit Deployments und Datenbank-Strategien.
Lift-and-Shift vs Refactoring: Migration im Vergleich
Lift-and-Shift oder Refactoring für Kubernetes? Entscheidungsmatrix, praktische Beispiele und das Strangler-Fig-Pattern als Mittelweg für Legacy-Migrationen.
Legacy-Anwendungen auf Kubernetes migrieren: Anleitung
Legacy-Anwendungen auf Kubernetes migrieren: Vier Migrationsmuster von Lift-and-Shift bis Rebuild mit Schritt-für-Schritt-Anleitung und YAML-Beispielen.
Shared Database in Kubernetes: Schema-per-Service richtig umsetzen
Shared Database in Kubernetes mit Schema-per-Service Pattern: PostgreSQL StatefulSet Setup, Flyway-Migrations und Zugriffskontrolle für Microservices.
Kubernetes CQRS Pattern Microservices in Deutschland optimal nutzen
Optimieren Sie Skalierbarkeit und Performance Ihrer komplexen Microservices auf Kubernetes in Deutschland mit dem CQRS Pattern. Erfahren Sie, wie diese zukunftsweisende Architektur Compliance-Anforderungen erfüllt und digitale Souveränität für deutsche Unternehmen sichert.