Software-Modernisierung in Java

Das Fallbeispiel beschreibt das Aufteilen eines 20 Jahre alten Java-Monolithen in einzelne Services mit Hilfe des Strangler Fig-Patterns.

Software-Modernisierung in Java

Branche: Fahrzeugleasing

Aufgabenstellung: Modernisierung eines Software-Systems für die Berechnung- und Erstellung von Leasing-Angeboten für Fahrzeuge. 

Programmiersprache: Java, JSP

Datenbank: Oracle

Architekturstil: Monolith, unstrukturiert

Betriebsplattform: Unix, Apache, Microsoft Azure

Warum Software-Modernisierung?

Die Leasing-Anwendung unterliegt einem nicht-trivialen Änderungsdruck. Um wirtschaftlich erfolgreich zu bleiben, muss der Anbieter diesem Druck nachgeben und die Software anpassen. Die primären Treiber des Änderungsdrucks sind "Unzureichende Funktionalität" und "Schlechte Performance". Der Änderungsdruck ist nicht-trivial, da er sich nicht mit angemessenem Aufwand lösen lässt.

Änderungstreiber "Unzureichende Funktionalität" 

Das System unterstützt existierende Geschäftsprozesse nur noch unzureichend. Die Anpassung bestehender und die Entwicklung neuer Funktionalität ist aufwändig, zeitintensiv, risikobehaftet und teuer. Folglich wird das System nur noch angepasst oder erweitert, wenn dies absolut erforderlich wird. 

Der Änderungsdruck ist hoch. Systemanpassungen sind betriebswirtschaftlich zweifelhaft, da deren Kosten den zu erwartenden Einnahmen übersteigen. Aufgrund zunehmend unpassenderer Funktionalität wechseln Kunden den Anbieter.

Ursachen

Wartbarkeit: Die monolithische Java-Anwendung ist über Jahrzehnte zunehmend unwartbarer geworden. Die Code-Qualität ist schlecht. Es gibt weder Architekturregeln noch klare Modulgrenzen. Die schwer abgrenzbaren Module sind zudem eng gekoppelt und verfügen über geringe Kohäsion. Es existieren keine automatisierten Tests. 

Dokumentation: Der Quellcode und die zugrundeliegende Architektur sind nicht dokumentiert. Es gibt keine Architecture Decision-Records. 

Fehlende Entwickler: Das System ist schwer zu verstehen. Jede Änderung führt zu nicht absehbaren Seiteneffekten und ist damit höchst risikobehaftet. Die noch vorhandenen Entwickler sind unzufrieden, fühlen sich unproduktiv. Neue Entwickler sind nur schwer zu finden. 

Änderungstreiber "Schlechte Performance"

Die Berechnung von Leasingangeboten dauert lange. Kunden warten bis zu zehn Sekunden auf Ergebnisse und verlassen häufig nach dem ersten Versuch die Plattform.

Der Änderungsdruck ist hoch. Die Berechnung von Leasingangeboten ist die erste Funktion, die von Neukunden genutzt wird. Der Ersteindruck ist schlecht. Viele Neukunden gehen verloren. 

Ursachen

Wartbarkeit: Der Code für die Angebotsberechnung ist schlecht modularisiert und ohne klare Regeln über das System verteilt. Es ist nicht erkennbar, welche Code-Stellen für einen Performance-Gewinn optimiert werden müssen. Die Verteilung des betroffenen Sourcecodes über das System macht dessen Änderungen aufgrund mangelnder Testautomatisierung und zu erwartender Seiteneffekte sehr risikoreich.

Suboptimale Datenbankstruktur: Das Datenmodell der Anwendung wurde über Jahrzehnte entwickelt. Der Fokus der Weiterentwicklung lag primär auf Erweiterungen. Anpassungen und Optimierungen wurden weitestgehend vermieden. In der Folge hat sich das Datenmodell zunehmend vom Domänenmodell der Anwendung entfernt. Die für die Angebotskalkulation benötigten Daten müssen über viele Tabellen hinweg zusammengesucht und gejoined werden, was erhebliche Performance-Einbußen zur Folge hat.  

Modernisierungsstrategie

Das Angebotssystem des Leasinganbieters ist dessen zentrales System, das maßgeblich für den Geschäftserfolg des Unternehmens verantwortlich ist. Eine Neuentwicklung kam aufgrund des hohen Risikos sowie der nicht abschätzbaren Dauer und Kosten nicht in Frage. Stattdessen hat sich der Anbieter für die iterative und inkrementelle Sanierung des Bestandssystems entschieden.

Fokus "Schlechte Performance"

Aufgrund des hohen Änderungsrucks durch die Performance-Probleme begann die Sanierung mit der Optimierung der Angebotsberechnung. Aufgrund der schlechten Wartbarkeit des Monolithen hat sich das Modernisierungs-Team für die Extraktion der Angebotsberechnung in einen eigenen Service gemäß des Strangler Fig-Musters entschieden. Dem Service wurde eine noSQL-Datenbank mit Performance-optimierten Angebotsdaten zur Verfügung gestellt. Exportprozesse befüllen diese Datenbank regelmäßig mit den angebotsrelevanten Daten des Monolithen. 

Der Angebotsservice konnte schnell und mit hoher Qualität entwickelt werden. Änderungen am Bestandssystem wurden weitestgehend vermieden und das damit verbundene Risiko konnte minimiert werden. Auf der anderen Seite stellte das Synchronhalten der Daten zwischen Monolith und Angebotsberechnungs-Service ein fortdauerndes Problem dar. Fehlschlagende oder verzögerte Exports führten regelmäßig zu Abweichung zwischen berechneten und erstellten Angeboten. Das Problem abweichender Daten konnte erst durch Extraktion des Angebotserstellungs-Service und dessen Umstellung auf die vom Angebotsberechnungs-Service verwendete Datenquelle auf ein akzeptables Maß verbessert werden.

Fokus "Unzureichende Funktionalität"

Das Modernisierungsteam hat entschieden, dass sich die schlechte Wartbarkeit und die daraus resultierende schlechte Anpassbar- und Erweiterbarkeit nur durch die Extraktion weiterer Services in den Griff kriegen lässt. Nach und nach wurden einzelne Funktionen gemäß dem [Strangler Fig]-Pattern extrahiert und in besser wartbare Services verschoben.

Der verwendete Modularisierungsansatz führte zu einer besseren Skalierbarkeit des größer werdenden Entwicklungsteams. Allerdings ist das Zerlegen eines Monolithen in Services auch die hohe Schule der Softwareentwicklung und sollte neben der reinen Modularisierung weiter begründet werden, z.B. durch abweichende Skalierbarkeits- oder Sicherheitsanforderungen unterschiedlicher Services. Fehlen diese Argumente und besteht keine Notwendigkeit der Skalierung des Entwicklungsteams, dann sollte zunächst über eine interne Remodularisierung des Monolithen, z.B. mit Methoden des Domain-driven Designs und Hexagonaler Architekturen nachgedacht werden.