Legacy-Software schrittweise modernisieren
Ich unterstütze Ihr Entwicklungsteam dabei, gewachsene Software im laufenden Betrieb zu modernisieren – Schritt für Schritt nach dem Strangler Pattern. Ziel ist, dass neue Funktionen wieder schneller live gehen und sich Laufzeitumgebung, Frameworks und Abhängigkeiten wieder sicher aktualisieren lassen.
01 Das Angebot
Modernisierung im laufenden Betrieb, als Teil Ihres Teams
Dieses Angebot richtet sich an Unternehmen mit eigenem Entwicklungsteam und einer gewachsenen Anwendung, die einen zentralen Geschäftsprozess trägt: Aufträge, Flotten, Preise, Kundendaten. Die Software läuft, aber jede Änderung kostet mehr Zeit als früher, und ein Update der technischen Grundlage ist seit Jahren aufgeschoben.
Ich arbeite als erfahrener Entwickler in Ihrem Team mit. Gemeinsam bestimmen wir den Teil der Anwendung, bei dem eine Modernisierung den größten Nutzen bringt. Diesen Teil lösen wir schrittweise aus dem bestehenden System heraus und bringen ihn in Produktion, während die übrige Anwendung weiterläuft und Ihr Team weiter neue Funktionen ausliefert.
Ihr Team behält dabei die Verantwortung für seine Software. Das Wissen über die neue Lösung entsteht im Team und bleibt dort. Wie eine schrittweise Ablösung technisch funktioniert, zeigt der Artikel Altsysteme schrittweise ablösen an einem ausführlichen Beispiel.
02 Die Anlässe
Wann sich eine Modernisierung lohnt
Neue Funktionen dauern zu lange
In einer gewachsenen Anwendung berührt eine kleine fachliche Änderung oft viele Module. Mehrere Teams müssen ihre Releases abstimmen, Tests laufen lange oder fehlen, und niemand ändert gern den Kern, weil die Folgen schwer abzuschätzen sind. Dann bremst die Software das Unternehmen, nicht das Team.
Updates sind nicht mehr möglich
Laufzeitumgebung oder Framework haben das Ende ihres Supports erreicht. Eine Bibliothek lässt sich nicht aktualisieren, weil eine andere die neue Version nicht verträgt. Ein Penetrationstest, ein Audit oder der Sicherheitsfragebogen eines Kunden macht die veralteten Versionen sichtbar. Mehr dazu im Abschnitt Sicherheit.
Wissen und Kapazität fehlen
Die Menschen, die das alte System kennen, verlassen das Unternehmen. Das Team ist mit Fachanforderungen ausgelastet und hat weder Zeit noch Erfahrung, nebenbei eine Migration zu stemmen.
Nicht jede alte Software muss modernisiert werden. Trägt eine Anwendung ihren Prozess zuverlässig und lässt sich ihre technische Grundlage noch aktualisieren, reichen oft ein Update im Bestand und gezieltes Refactoring. Microsoft nennt als Grenzen des schrittweisen Umbaus unter anderem kleine Systeme, deren vollständiger Ersatz einfach ist, und Systeme, die kurzfristig ganz abgeschaltet werden sollen (Microsoft: Strangler Fig Pattern, „When to use this pattern“). Diese Einschätzung gehört für mich an den Anfang, nicht ans Ende.
03 Das Vorgehen
Schritt für Schritt nach dem Strangler Pattern
Das Strangler Fig Pattern beschreibt, wie neue Software neben dem Altsystem entsteht und nach und nach dessen Aufgaben übernimmt, bis das alte System abgeschaltet werden kann. Martin Fowler begründet das Vorgehen mit kleineren Risiken je Schritt und einem früheren Nutzen für das Unternehmen (Martin Fowler: Strangler Fig Application). In Ihrem Projekt sieht das so aus:
- Einen fachlichen Bereich wählen. Wir suchen den Teil der Anwendung, dessen Herauslösen am meisten bringt und der sich fachlich abgrenzen lässt, etwa die Terminplanung oder die Preisberechnung. Der Zuschnitt folgt dem Geschäftsprozess, nicht technischen Schichten (AWS: Zerlegung nach fachlichen Fähigkeiten).
- Anfragen über eine Fassade leiten. Ein API-Gateway oder Reverse Proxy nimmt alle Aufrufe an und leitet zunächst alles an das Altsystem weiter. Nach der Freigabe des neuen Teils übernimmt dieser seine Aufrufe. Für Aufrufer ändert sich nichts (Microsoft: Strangler Fig Pattern).
- Die Verbindung zum Altsystem begrenzen. Ein Adapter übersetzt zwischen altem Datenmodell und neuem Dienst, damit sich Eigenheiten des Altsystems nicht in die neue Lösung ziehen. Dafür entwickle ich bei Bedarf die Schnittstellen zum Bestand.
- Daten und Schreibverantwortung übertragen. Der Bestand wird übernommen, Änderungen werden nachgeführt und geprüft. Erst dann wechselt die Zuständigkeit für diese Daten zum neuen Dienst.
- Umschalten, Rückweg bereithalten, Altteile abschalten. Die Umschaltung wird geprüft und kann zurückgenommen werden. Nicht mehr benötigte Funktionen des Altsystems werden entfernt, damit nicht dauerhaft zwei Implementierungen gepflegt werden müssen.
Ihr Team liefert während der gesamten Zeit weiter neue Funktionen aus. Das Nebeneinander von alt und neu kostet zusätzliche Arbeit; Fowler hält diesen Preis für gerechtfertigt, solange die Übergangsbauten als vorübergehend geplant sind. Deshalb halten wir für jeden Schritt fest, welche alte Zuständigkeit damit entfällt.
Ausführlich mit Beispiel, Fassade, Anti-Corruption Layer, Datenübernahme und Rückweg: Altsysteme schrittweise ablösen.
04 Die Zielarchitektur
Microservices, wo sie passen
Die Überführung eines Monolithen in Microservices kann sinnvoll sein, wenn fachliche Bereiche unabhängig voneinander verändert, bereitgestellt oder skaliert werden sollen und wenn mehrere Teams an derselben Anwendung arbeiten. Jeder Dienst verantwortet dann einen Bereich samt seiner Daten. Voraussetzung ist ein Betrieb, der mehrere Dienste ausliefern, überwachen und Fehler über Dienstgrenzen hinweg verfolgen kann. Microsoft nennt dafür ausdrücklich eine ausgereifte DevOps-Kultur und die passenden Fähigkeiten im Team (Microsoft: Microservices-Architekturstil, „Challenges“).
Microservices sind nicht automatisch die richtige Wahl. Fowler weist darauf hin, dass gute und stabile Dienstgrenzen auch erfahrenen Architekten zu Beginn schwerfallen und dass der Betrieb vieler Dienste einen Aufwand verursacht, der sich nur bei entsprechend komplexen Systemen lohnt (Martin Fowler: Monolith First). Für eine überschaubare Anwendung oder ein einzelnes Team mit wenigen Abhängigkeiten prüfe ich deshalb zuerst einen modularen Monolithen: eine gemeinsam ausgelieferte Anwendung mit klar getrennten internen Bereichen. Manchmal ist auch ein Update im Bestand der bessere Weg.
Welche Architektur zu Ihrem System passt, entscheiden wir am konkreten Fall, nicht nach Trend. Wenn Microservices das Ziel sind, beschreibt mein Angebot zur Microservices-Entwicklung den Aufbau neuer Dienste; die Grundlagen erläutert der Artikel über verteilte Systeme. Laufen die neuen Teile in der Cloud, kommt die cloud-native Entwicklung auf AWS dazu.
05 Sicherheit
Updates wieder möglich machen
Veraltete Komponenten sind ein eigenes Sicherheitsrisiko. Die OWASP Top 10 führen „Vulnerable and Outdated Components“ auf Platz 6 und zählen dazu Software, die „vulnerable, unsupported, or out of date“ ist, einschließlich Laufzeitumgebungen und Bibliotheken, sowie Plattformen und Frameworks, die nicht zeitnah aktualisiert werden (OWASP Top 10:2021, A06).
Dass ein Update ausbleibt, liegt selten an Nachlässigkeit. Die Hersteller geben Supportzeiträume vor: PHP pflegt jeden Release-Zweig zwei Jahre aktiv und zwei weitere Jahre nur für kritische Sicherheitslücken, danach ist er abgekündigt (php.net: Supported Versions). Node.js garantiert für LTS-Versionen insgesamt 30 Monate Fehlerbehebung und empfiehlt für den Produktivbetrieb ausschließlich LTS-Versionen (nodejs.org: Previous Releases). Für Spring-Projekte nennt die Support-Richtlinie für Minor-Releases mindestens 13 Monate Open-Source-Support (spring.io: Support Policy). Wer ein Framework-Update mehrere Jahre aufschiebt, muss anschließend oft mehrere Hauptversionen auf einmal überspringen, und daran scheitern viele Updates im Bestand.
Die schrittweise Modernisierung hilft hier auf zwei Wegen. Neue Komponenten starten auf unterstützten Versionen; Abhängigkeiten werden regelmäßig und automatisiert geprüft, und eine Testpipeline macht Aktualisierungen zur Routine statt zum Projekt. Gleichzeitig schrumpft der alte Teil, und mit ihm die Fläche, die noch auf veralteten Versionen läuft. Wo ein Update im Bestand möglich ist, bleibt es der kleinere Schritt; auch das gehört zur gemeinsamen Einschätzung.
06 Zusammenarbeit
Zusammenarbeit mit Ihrem Team
Der Unterschied zu einer ausgelagerten Modernisierung: Ich arbeite in Ihrem Team, nicht daneben. Konkret bedeutet das:
- Ihre Werkzeuge und Abläufe. Ich arbeite in Ihren Repositories, Ihrer Build-Pipeline und Ihren Terminen, etwa Planung, Reviews und Bereitschaft für den Betrieb.
- Ein klar abgegrenzter Teil. Ich übernehme den vereinbarten Bereich der Modernisierung und entwickle ihn gemeinsam mit den Entwicklerinnen und Entwicklern, die ihn später weiterpflegen.
- Entscheidungen werden festgehalten. Architektur- und Zuschnittsentscheidungen treffen wir gemeinsam und dokumentieren sie dort, wo Ihr Team sie später findet.
- Ihr Team behält die Verantwortung. Quellcode, Infrastrukturdefinitionen und Dokumentation gehören Ihnen und liegen in Ihren Systemen. Die Übergabe planen wir von Anfang an mit, damit Ihr Team nach dem Projekt ohne mich weiterarbeiten kann.
Verantwortung im laufenden Betrieb ist mir vertraut: Bei MOIA, Jungheinrich und VTG war ich als First Responder Ansprechpartner bei Störungen, Dateninkonsistenzen und Leistungsproblemen, bei MOIA zusätzlich als Technical Designer an unternehmensweiten Architekturentscheidungen beteiligt (mehr dazu auf der Seite über mich).
Ich lebe in Hamburg und arbeite dort auf Wunsch bei Ihnen vor Ort. Überregional arbeite ich primär remote; einzelne Termine vor Ort sind nach Absprache möglich. Seit 2016 habe ich überwiegend in internationalen, englischsprachigen Teams gearbeitet; Deutsch oder Englisch als Arbeitssprache sind beide möglich.
07 Projekterfahrung
Modernisierung im laufenden Betrieb bei Jungheinrich
Bei Jungheinrich wirkte ich an der schrittweisen Modernisierung des Flottenmanagements mit. Die bestehende Anwendung blieb im Einsatz, während sie weiterentwickelt und um neue Funktionen ergänzt wurde. Zu meinem Beitrag gehörten:
- die gemeinsame Konzeption einer schrittweisen Ablösung bestehender Systemteile,
- die Entwicklung von Backend-Diensten und Schnittstellen für Fahrzeuganbindung und Batteriemanagement,
- Weboberflächen und Funktionen für die nächste Generation des Flottenmanagements,
- die Beteiligung an Bereitstellung und laufendem Betrieb.
Dabei kamen verteilte Systeme, Microservices und Event Sourcing zum Einsatz. Die Referenz zur Modernisierung des Flottenmanagements beschreibt das Projekt.
Erfahrung mit der Arbeit in größeren Organisationen bringe ich außerdem aus MOIA und VTG mit: Backend-Dienste und Schnittstellen in Umgebungen mit mehreren Teams und produktivem Betrieb. Beides waren keine Modernisierungsprojekte, aber dieselbe Arbeitsweise: ein abgegrenzter Verantwortungsbereich innerhalb eines bestehenden Teams.
08 Der Einstieg
Der erste Schritt
Am Anfang steht ein kostenloses, unverbindliches Gespräch von 30 Minuten. Sie beschreiben Ihr System, Ihr Team und den Engpass; ich sage Ihnen offen, ob eine schrittweise Modernisierung passt und ob ich der Richtige dafür bin.
Danach schauen wir gemeinsam auf das System: Welche Bereiche gibt es, wer ruft sie auf, welche Daten teilen sie sich, und welcher Teil kommt als erster Schritt in Frage? Aus dieser Bestandsaufnahme entstehen der Zuschnitt des ersten Teilstücks und eine Aufwandsschätzung dafür. Die Zusammenarbeit rechne ich nach tatsächlichem Aufwand ab; eine Schätzung für den abgegrenzten Umfang erhalten Sie auf Wunsch vorab.
09 Fragen
Fragen zur Software-Modernisierung
Müssen wir unsere Software dafür komplett neu entwickeln?
Nein. Die schrittweise Modernisierung ersetzt gezielt die Teile, bei denen Veränderung heute am meisten kostet. Andere Teile bleiben, solange sie ihre Aufgabe erfüllen und sich aktualisieren lassen. Manchmal zeigt die Bestandsaufnahme auch, dass ein Update im Bestand reicht und kein Umbau nötig ist.
Können wir währenddessen weiter neue Funktionen ausliefern?
Ja, das ist der Zweck des schrittweisen Vorgehens. Die Fassade leitet Aufrufe an alt oder neu, und jeder Schritt hat einen begrenzten fachlichen Umfang. Dafür müssen Sie einen Preis einkalkulieren: Solange alte und neue Teile nebeneinander laufen, kosten Abstimmung, Datenabgleich und doppelte Zuständigkeiten zusätzliche Arbeit. Deshalb planen wir für jeden Schritt den Abbau des alten Teils ein.
Wann sind Microservices nicht die richtige Wahl?
Wenn eine Anwendung überschaubar ist, ein einzelnes Team sie betreut und die fachlichen Bereiche ohnehin gemeinsam verändert werden. Dann verursachen mehrere Dienste Betriebs- und Abstimmungsaufwand ohne entsprechenden Nutzen. Ein modularer Monolith mit klaren internen Grenzen ist dann der passendere Schritt; aus ihm lassen sich Dienste später herauslösen, wenn der Bedarf entsteht.
Wie arbeiten Sie mit unserem bestehenden Team zusammen?
Als Teil des Teams: in Ihren Repositories, Ihrer Pipeline und Ihren Terminen. Ich übernehme einen abgegrenzten Bereich, treffe Entscheidungen gemeinsam mit dem Team und halte sie schriftlich fest. Ziel ist, dass Ihr Team die neue Lösung nach dem Projekt selbst weiterentwickelt und betreibt.
Mit welchen Technologien arbeiten Sie?
Kotlin, Go, Java und Spring Boot, TypeScript und React sowie PHP; dazu PostgreSQL, DynamoDB und MongoDB, Cloud-Infrastruktur auf AWS, Microservices und ereignisgetriebene Architekturen. Für Mainframe-, COBOL- oder SAP-Modernisierungen bin ich nicht der richtige Ansprechpartner.
Wie lange dauert eine Modernisierung, und was kostet sie?
Das hängt vom System ab, nicht von der Methode. Den Aufwand des ersten Schritts bestimmen der Zuschnitt des Teilstücks, seine Aufrufer, seine Daten und die Teams, von denen es abhängt. Deshalb nenne ich keine Pauschalen, sondern schätze nach der gemeinsamen Bestandsaufnahme den abgegrenzten ersten Schritt. Abgerechnet wird nach tatsächlichem Aufwand.
