Vertikalisierung
Vertikalisierung ist ein Muster für die Aufteilung einer Entwicklungsorganisation in vertikale Teams, die möglichst unabhängig voneinander arbeiten können. Das Muster eignet sich sehr gut für die Skalierung großer Entwicklungsorganisationen. Software-architektonisch forciert das Muster Microservice-Architekturen. Diese sind gekennzeichnet durch kohärente und lose gekoppelte Services, die über klar definierte Schnittstellen miteinander kommunizieren. Richtig umgesetzt führt Vertikalisierung zu hoch flexiblen Architekturen, deren Services unabhängig voneinander entwickelt, betrieben und skaliert werden können.
Microservices als Allheilmittel
Microservice-basierte Architekturen sind einer der am weitverbreitetsten Architekturstile unserer Zeit. Greenfield-Projekte starten unabhängig von erforderlichen Architekturcharakteristiken mit dem Aufteilen in Services und enden nicht selten bei einem hoch flexiblen und skalierbaren System, kurz bevor ihnen das Geld ausgeht. Legacy-Projekte erhoffen sich durch das Extrahieren von Services die mittelfristige Erdrosselung ihres Monolithen (siehe Strangler Fig), um festzustellen, dass die Komplexität nicht sinkt, sondern zunimmt. Das gleiche gilt für die Betriebskosten: Statt einen Monolithen auf einer EC2-Instanz zu betreiben, verzehnfacht sich jetzt der Maschinenbedarf.
Am Ende geht es immer wieder um Modularisierung
Modularisierung ist seit dem 1972 erschienenen Papier von Parnas (siehe Parnas) eines der zentralen Prinzipien der Softwareentwicklung. Modularisierung soll helfen, Komplexität in den Griff zu bekommen, indem Systeme in kohärente und lose gekoppelte Module aufgeteilt werden, die von einzelnen Personen oder Teams verstanden und entwickelt werden können. Modularisierung verringert die mentale Last des einzelnen, begrenzt die Auswirkungen von Seiteneffekten und ist eine der Grundvoraussetzungen für die Entwicklung wartbarer Software.
Microservices forcieren Modularisierung, indem sie Interservice-Interaktion möglichst schwierig machen. Während sich Modulgrenzen innerhalb eines Monolithen leicht verletzen lassen, müssen Interaktionen zwischen Services aufwändig verhandelt werden. Dieser Aufwand erzwingt Modularisierung und unabhängige Services. Auf der anderen Seite bringen durch das Netzwerk geschützte Modulgrenzen eine ganze Reihe von Nachteilen mit sich: Netzwerk- und Security-Latenzen, verteilte Datenhaltung, unklare Datenhoheit, verteilte Transaktionen, erschwerte Fehlerbehandlung, hohe Betriebskosten. Diese Nachteile gilt es gegen die Vorteile, wie Flexibilität, Skalierbarkeit und strenge Modularisierung abzuwägen.
Modulithen
Modularisierung ist die Grundvorrausetzung für die Entwicklung wartbarer Software. Aber was lässt uns annehmen, dass wir Microservice-Architekturen bauen können, wenn wir in der Vergangenheit immer wieder an der Entwicklung sauber modularisierter Monolithen gescheitert sind? Ich habe mir diese Frage oft gestellt und bis heute keine Antwort gefunden. Stattdessen mehren sich die Zeichen aus der Community, dass der eingeschlagene "Microservices für alles"-Weg vielleicht doch nicht immer der Beste ist. So konnte Amazon mit der Devertikalisierung seiner Service-basierten Prime-Architektur nicht nur ein stark vereinfachtes System bauen, sondern zusätzlich 90% an Betriebskosten einsparen (siehe Amazon Prime). Darüber hinaus deuten unsere Kundenanfragen darauf hin, dass ihr aktuelles System zwar hoch flexibel skaliert werden kann, diese Skalierung aber derzeit gar nicht benötigt wird. Stattdessen denkt man darüber nach, Teams zu reduzieren und Services zusammenzulegen, nicht zuletzt aus wirtschaftlichen Gründen.
Zeit für Devertikalisierung
Ich halte Vertikalisierung weiterhin für ein geeignetes Muster für die Skalierung großer Entwicklungsorganisationen. Weniger Abstimmung, weniger Meetings und schmale Kommunikationskanäle sind unbestreitbare Vorteile und im Sinne fast aller Entwickelnden. Auf der anderen Seite sind vertikalisierte Teams und Microservice-basierte Architekturen die hohe Schule der Softwareentwicklung. Wir müssen uns fragen, ob wir die Vorteile dieses Architekturstils wirklich brauchen und ob wir die damit einhergehende Komplexität im Griff haben.
Viele Microservice-basierte Systeme sind in den letzten Jahren aus dem Ruder gelaufen. Live-gänge werden immer weiter in die Zukunft geschoben. Der parallel zur service-basierten Neuentwicklung betriebene Monolith wird von Jahr zu Jahr weitergepflegt und um neue Features erweitert. Verantwortliche müssen sich die Frage gefallen lassen, warum das System überhaupt neu entwickelt wird, wenn der Monolith doch eigentlich ganz gut funktioniert.
Beispiele wie Amazon zeigen, dass es Zeit wird, über Devertikalisierung, d.h. die Rückführung von Service-basierten Architekturen in modularisierte Monolithen nachzudenken. Wir benötigen Muster und Techniken, die diese schrittweise Zusammenführung unterstützen. Diese Muster und weitere Praxisbeispiele werden wir in den kommenden Monaten und Jahren sehen.
Referenzen
Strangler Fig: https://martinfowler.com/bliki/StranglerFigApplication.html