Legacy-Modernisierung
Strangler Fig Pattern: Legacy-Systeme schrittweise ablösen
Ich habe mehr Big-Bang-Rewrites scheitern sehen als erfolgreich live gehen. Das Strangler Fig Pattern – benannt nach der Würgefeige, die ihren Wirtsbaum langsam umschließt – ist nicht elegant. Aber es ist das Einzige, das unter realem Druck zuverlässig funktioniert. Statt eines riskanten Komplett-Austauschs ersetzen Sie Funktionalität schrittweise, während das alte System weiterläuft.
Warum das Strangler Fig Pattern?
Die meisten Legacy-Modernisierungen scheitern nicht an technischen Problemen, sondern an Risiko-Management. Ein Big-Bang-Rewrite bedeutet:
- Monate ohne Releases: Während des Rewrites gibt es keine neuen Features
- Hohes Risiko: Am Go-Live-Tag muss alles funktionieren – oder nichts
- Wissenverlust: Implizites Geschäftswissen im alten Code geht verloren
- Moving Target: Anforderungen ändern sich während der langen Entwicklung
Das Strangler Fig Pattern löst diese Probleme durch inkrementelle Migration:
| Big Bang Rewrite | Strangler Fig Pattern |
|---|---|
| Alles oder nichts | Schrittweise Migration |
| Lange ohne Releases | Kontinuierliche Deployments |
| Hohes Risiko am Go-Live | Risiko verteilt auf viele kleine Schritte |
| Rollback = Komplett-Rollback | Rollback pro Feature möglich |
| Team blockiert für Monate | Parallele Feature-Entwicklung möglich |
Das Grundprinzip
Die Metapher der Würgefeige beschreibt den Prozess perfekt: Die Feige wächst an einem Wirtsbaum hoch, umschließt ihn langsam, und übernimmt schließlich dessen Platz – während der Wirtsbaum abstirbt.
Übertragen auf Software:
- Facade einrichten: Ein Proxy/Gateway leitet Traffic zwischen altem und neuem System
- Neue Funktionen im neuen System: Alles Neue wird nur noch modern gebaut
- Schrittweise Migration: Bestehende Funktionen werden nach und nach ins neue System übertragen
- Legacy abschalten: Wenn keine Requests mehr ans alte System gehen, wird es abgeschaltet
Architektur-Varianten
URL-basiertes Routing
Die einfachste Variante: Ein Reverse Proxy (Nginx, HAProxy) routet basierend auf URL-Pfaden:
# nginx.conf
upstream legacy {
server legacy-app:8080;
}
upstream modern {
server modern-app:3000;
}
server {
listen 80;
# Neue Module -> modernes System
location /api/v2/ {
proxy_pass http://modern;
}
location /users/ {
proxy_pass http://modern;
}
# Alles andere -> Legacy
location / {
proxy_pass http://legacy;
}
}
Feature-Toggle-basiertes Routing
Für feinere Kontrolle: Feature Flags entscheiden zur Laufzeit, welches System einen Request bearbeitet:
class OrderService {
public function createOrder(array $data): Order {
if ($this->featureFlags->isEnabled('new-order-system', $this->user)) {
return $this->modernOrderService->create($data);
}
return $this->legacyOrderService->create($data);
}
}
Das ermöglicht:
- Canary Releases: Erst 1% der User, dann 10%, dann 50%, dann alle
- A/B-Testing: Vergleich von altem und neuem System
- Sofortiges Rollback: Flag ausschalten = zurück zum Legacy-System
Event-basierte Migration
Für komplexere Szenarien: Beide Systeme reagieren auf Events, das neue System übernimmt schrittweise die Verarbeitung:
// Legacy-System published weiterhin Events
$eventBus->publish(new OrderCreatedEvent($order));
// Modernes System subscribed und baut eigenen State auf
class ModernOrderProjector {
public function onOrderCreated(OrderCreatedEvent $event): void {
// Eigene Datenhaltung aufbauen
$this->repository->save(
Order::fromLegacyEvent($event)
);
}
}
Migrations-Strategien
Asset Capture
Beginnen Sie mit den „Assets" – den wertvollen Teilen des Systems, die am meisten Geschäftswert liefern:
- Identifizieren Sie die wichtigsten Geschäftsprozesse
- Migrieren Sie diese zuerst ins neue System
- Weniger wichtige Funktionen folgen später (oder werden eingestellt)
Anti-Corruption Layer
Ein Anti-Corruption Layer (ACL) übersetzt zwischen den Domänenmodellen von alt und neu:
class LegacyOrderAdapter implements OrderRepositoryInterface {
public function __construct(
private LegacyDatabase $legacyDb,
private OrderMapper $mapper
) {}
public function findById(OrderId $id): ?Order {
$legacyData = $this->legacyDb->query(
"SELECT * FROM orders WHERE id = ?",
[$id->value()]
);
if (!$legacyData) {
return null;
}
// Legacy-Datenstruktur in moderne Domain-Objekte übersetzen
return $this->mapper->toDomainObject($legacyData);
}
}
Branch by Abstraction
Führen Sie Abstraktionen ein, bevor Sie migrieren:
- Abstraktion einführen: Interface vor die Legacy-Implementierung setzen
- Clients umstellen: Alle Aufrufer nutzen das Interface
- Neue Implementierung: Moderne Implementierung des Interfaces bauen
- Umschalten: Per Feature Flag oder Konfiguration zwischen Implementierungen wechseln
- Legacy entfernen: Alte Implementierung löschen
Daten-Migration
Die Datenmigration ist oft der komplexeste Teil. Strategien:
Dual Write
Während der Migration schreiben Sie in beide Systeme:
class OrderService {
public function createOrder(array $data): Order {
// Transaktion für Konsistenz
$this->db->beginTransaction();
try {
// Legacy-System
$legacyOrder = $this->legacyOrderService->create($data);
// Modernes System
$modernOrder = $this->modernOrderService->create($data);
$this->db->commit();
// Feature Flag entscheidet, welches zurückgegeben wird
return $this->featureFlags->isEnabled('read-from-modern')
? $modernOrder
: $legacyOrder;
} catch (Exception $e) {
$this->db->rollback();
throw $e;
}
}
}
Change Data Capture (CDC)
Tools wie Debezium lesen das Transaction Log der Legacy-Datenbank und streamen Änderungen ins neue System:
# docker-compose.yml für Debezium
debezium:
image: debezium/connect:2.4
environment:
BOOTSTRAP_SERVERS: kafka:9092
GROUP_ID: legacy-cdc
CONFIG_STORAGE_TOPIC: cdc_configs
OFFSET_STORAGE_TOPIC: cdc_offsets
# Connector-Konfiguration
{
"name": "legacy-orders-connector",
"config": {
"connector.class": "io.debezium.connector.postgresql.PostgresConnector",
"database.hostname": "legacy-db",
"database.port": "5432",
"database.user": "cdc_user",
"database.password": "****",
"database.dbname": "legacy",
"table.include.list": "public.orders,public.order_items",
"topic.prefix": "legacy"
}
}
Typische Fallstricke
1. Zu große Schritte
Das Strangler Fig Pattern funktioniert nur mit kleinen, überschaubaren Schritten. Ich habe Teams gesehen, die „nur noch dieses eine große Feature" ins neue System migrieren wollten – sechs Monate später lief immer noch beides parallel, und keiner wusste mehr, welches System die Wahrheit enthielt.
Lösung: Maximal 2-4 Wochen pro Migrations-Schritt. Lieber öfter deployen.
2. Kein Monitoring
Ohne Metriken wissen Sie nicht, ob die Migration erfolgreich ist:
- Wie viel Traffic geht noch ans Legacy-System?
- Wie ist die Error-Rate im neuen System?
- Gibt es Performance-Unterschiede?
Lösung: Dashboards für beide Systeme mit Vergleichsmetriken.
3. Legacy wird nie abgeschaltet
Das ist der schleichende Tod jeder Migration. Die letzten 10% bleiben ewig im Legacy-System. „Das machen wir später" wird zum Mantra. Zwei Jahre später bezahlen Sie für zwei Systeme, zwei Wartungsverträge, zwei Entwicklerteams – und niemand will mehr an das alte System fassen.
Lösung: Deadline setzen. Verbindlich. Nach Datum X wird Legacy abgeschaltet – notfalls werden verbleibende Features eingestellt. Dieser Termin muss im Management-Report stehen. Und hier die harte Wahrheit: Wenn es keine Entscheidungsebene gibt, die bereit ist, Altlasten wirklich abzuschalten, scheitert jede Migration – egal wie gut die Architektur ist.
4. Fehlende Daten-Konsistenz
Bei Dual Write oder parallelem Betrieb können Daten divergieren. Ich habe Fälle erlebt, wo morgens das Sales-Team andere Zahlen sah als das Controlling – weil ein System drei Sekunden schneller war als das andere. Solche Inkonsistenzen zerstören das Vertrauen in die Migration schneller als jeder Bug.
Lösung: Reconciliation-Jobs, die regelmäßig Daten zwischen beiden Systemen vergleichen und Unterschiede melden. Automatische Alerts, bevor das Business die Differenzen entdeckt.
Praxis-Beispiel: E-Commerce-Migration
Ein mittelständischer Online-Shop mit 15 Jahre altem Monolithen. Die Migration dauerte 18 Monate:
| Phase | Dauer | Migrierte Komponenten |
|---|---|---|
| 1. Setup | 2 Monate | API Gateway, CI/CD, Monitoring |
| 2. Produktkatalog | 3 Monate | Produkte, Kategorien, Suche |
| 3. User-Management | 2 Monate | Login, Profile, SSO |
| 4. Warenkorb | 3 Monate | Cart, Checkout, Payment |
| 5. Bestellungen | 4 Monate | Orders, Fulfillment, Returns |
| 6. Admin & Reporting | 3 Monate | Backend, Analytics |
| 7. Cleanup | 1 Monat | Legacy abschalten |
Während der gesamten 18 Monate lief der Shop ohne Unterbrechung. Neue Features wurden ab Monat 3 nur noch im neuen System entwickelt.
Hilfreiche Tools
- API Gateway: Kong, AWS API Gateway, Traefik – für URL-basiertes Routing
- Feature Flags: LaunchDarkly, Unleash, Flagsmith – für Feature-Toggle-basierte Migration
- CDC: Debezium, AWS DMS – für Daten-Synchronisation
- Monitoring: Datadog, Grafana – für Vergleichsmetriken
- Testing: Contract Testing (Pact), Chaos Engineering – für Migrations-Sicherheit
Fazit
Das Strangler Fig Pattern ist keine Silberkugel – aber es ist der Ansatz, der in der Praxis am häufigsten funktioniert. Der Schlüssel liegt in:
- Kleine Schritte: Maximal 2-4 Wochen pro Migration
- Kontinuierlicher Betrieb: Beide Systeme laufen parallel
- Messbarkeit: Monitoring zeigt Fortschritt und Probleme
- Commitment: Deadline für Legacy-Abschaltung setzen
Häufige Fragen
Wie lange dauert eine Strangler Fig Migration?
Je nach Systemgröße 6-24 Monate. Kleinere Systeme schneller, Enterprise-Monolithen länger. Entscheidend ist, dass Sie nach wenigen Wochen den ersten echten Traffic über das neue System routen – nicht nach Monaten.
Kann ich das Pattern auch für Datenbank-Migrationen nutzen?
Ja, aber es ist komplexer. Change Data Capture (CDC) oder Event Sourcing sind hier die bevorzugten Mechanismen. Dual Write nur als letzte Option.
Was, wenn das Legacy-System nicht mehr gewartet werden kann?
Dann ist das Strangler Fig Pattern erst recht die richtige Wahl – Sie können das Legacy-System einfrieren und nur noch das neue System weiterentwickeln.
Brauche ich ein separates Team für die Migration?
Nicht unbedingt. Oft ist es besser, wenn das bestehende Team beides macht – so bleibt das Wissen über das Legacy-System erhalten und fließt in die neue Implementierung ein.
Legacy-System modernisieren?
Ich analysiere Ihr bestehendes System und entwickle eine Migrations-Strategie – ohne Risiko für den laufenden Betrieb.
Kostenlose Erstanalyse anfragen