© Enkel/Shutterstock.com
Von der Entstehung eines Monolithen und dem Versuch, ihn zu zerlegen

(Try to) Kill your Monolith


Bei der Entwicklung von Softwaresystemen und -architekturen gibt es verschiedene Ansätze und Paradigmen, die jeweils kontextabhängige Vor- und Nachteile haben. Zu gerne folgen wir bei der Beurteilung von Architekturen entweder unseren persönlichen Vorlieben oder wir verurteilen Lösungen, die nicht mehr State of the Art oder zu komplex sind, um sie mit überschaubarem Aufwand zu überblicken. Eine objektive Beurteilung einer gewachsenen Architektur kann aber nur auf einer strukturierten und sachlichen Analyse basieren.

Im Rahmen dieses Artikels geht es uns darum, den Leser auf eine wertungsfreie, zum Teil fiktive historische Reise mitzunehmen. In deren Rahmen beschreiben wir die Entstehung und das Wachstum eines Monolithen sowie die Herausforderungen beim Versuch, ihn zu modernisieren und zu zerlegen.

State of the Art sind derzeit Microservices-basierte Architekturen. Monolithische Architekturen sind verpönt, obwohl sie durchaus auch Vorteile haben können. Die Beurteilung einer Architektur bzw. eines größeren, historisch gewachsenen Systems ist insofern schwierig, als bei der Beurteilung nicht nur technische, sondern auch wirtschaftliche, organisatorische und fachliche Aspekte sowie die historischen Rahmenbedingungen berücksichtigt werden müssen.

Die Historie spielt bei der Bewertung eine wichtige Rolle. Designentscheidungen folgen nicht selten aktuellen Trends und basieren auf den zum jeweils aktuellen Zeitpunkt verfügbaren technischen Mitteln. Technologien, die heute angesagt sind, sind es ein paar Jahre später häufig nicht mehr – auch wenn sie ihren Zweck weiterhin gleichwertig erfüllen. Eine heute richtig wirkende Lösung könnte sich in Zukunft aufgrund eines sich im Kern veränderten Produkts als nicht mehr richtig erweisen. In diesem Fall muss bei der Bewertung differenziert werden: Liegt der Fehler im ursprünglichen Design oder beim Versäumnis einer Anpassung des Systems an die evolutionären Produktänderungen? Bei einem Versäumnis könnten die Ursachen organisatorischer Natur sein.

Als Beispiele dienen hier das Fehlen von Regeln und Maßnahmen zur Erfassung und Beseitigung technischer Schulden oder ein zu hoher erzwungener Durchsatz bei der Umsetzung neuer Anforderungen und das damit verbundene ständige Stricken mit der heißen Nadel. Oder aber ein Design wirkt nur falsch, weil eine hohe fachliche Komplexität auf das technische Design ausstrahlt und es schwerer greifbar macht. Hierbei verhält es sich wie in der Physik mit dem Energieerhaltungsprinzip: Komplexität lässt sich nicht einfach durch andere bzw. neuere Technologien beseitigen. Änderungen der Gesamtarchitektur ohne das nötige Verständnis bergen die Gefahr, die Konsequenzen nicht zu verstehen. Sie können den Gesamtwert des Produkts maßgeblich beeinträchtigen, ohne dass es rechtzeitig bemerkt wird.

Gerade die Historie ist es, die zu häufig ignoriert wird, obwohl sie spannend und aufschlussreich zugleich sein kann. In diesem Sinne beginnen wir nun also unsere Reise.

Es war einmal ...

Begeben wir uns eine Dekade zurück und werfen einen Blick auf zusammengetragene Erfahrungen zur Entstehung eines Monolithen. Wir schreiben das Jahr 2010 – wir gehen also gerade mal zehn Jahre zurück. Dabei werden wir einige Architekturprinzipien und Patterns betrachten.

Generell gilt, dass man eine Architektur nur auf Basis von Patterns und Prinzipien beurteilen kann, und das Wissen um diese sollte daher vorhanden sein. Zur Orientierung dienen kann SOLID [1] oder eine der wichtigsten Eigenschaften nachhaltiger Architekturen „Lose Kopplung und hohe innere Kohärenz“. Das Nichteinhalten bewährter Patterns und Paradigmen bei der Umsetzung kann Ursachen wie fehlendes Wissen oder durch Zeitdruck begründete mangelnde Kapazitäten haben. Jeder von uns wird sich mit diesen Punkten sicherlich schon konfrontiert gesehen haben – bewusst oder unbewusst. Durch fehlendes Wissen und der aus der Psychologie bekannten Verfügbarkeitsheuristik [2] läuft jeder einzelne von uns Gefahr, voreilige Schlüsse zu ziehen.

Wir beginnen die Entwicklung einer Applikation mit der Anlage eines Repositories im Versionsverwaltungssystem. Das Team umfasst initial einige wenige Entwickler. Die Frage nach dem korrekten fachlichen und technischen Schnitt lässt sich zu diesem Zeitpunkt nicht eindeutig beantworten, wodurch der Monolith-First-Ansatz durchaus richtig sein kann. So geht es also mit der Anlage des Repositories für die Applikation mit dem Namen A los. Es wird sauber gearbeitet und so erfolgt auch die Anlage der Jobs zur Continuous Integration (CI) in Hudson (Jenkins kam später). Die Software wird automatisch gebaut, getestet und paketiert und es werden Softwaremetriken erfasst. Maven in Version 2 wird als Build-System genutzt und ein Release erfolgt mit dem Maven-Release-Plug-in. Bei der Selektion der verwendeten Technologien und Frameworks setzt man weitestgehend auf das Neueste und nutzt u. a. Spring 2.5, JSF 1 und Java 6. Als Repository-Manager wird Nexus verwendet. Im Jahr 2010 wurde in der Fachwelt teilweise noch der Nutzen von Nexus diskutiert [3] und der Einsatz wurde erst allmählich selbstverständlich. Man darf sich also durchaus selbst auf die Schulter klopfen.

Abbildung 1 zeigt die zum derzeitigen Zeitpunkt noch sehr einfache Welt. Die Applikation A wird in einem zentralen Repository entwickelt. Das Ergebnis des Hudson-Build-Jobs ist ein WAR-Artefakt, das ins Nexus Repository publiziert wird. Das Deployment des WAR-Art...

Neugierig geworden? Wir haben diese Angebote für dich:

Angebote für Gewinner-Teams

Wir bieten Lizenz-Lösungen für Teams jeder Größe: Finden Sie heraus, welche Lösung am besten zu Ihnen passt.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang