Microservices vs. Monolith
Vor- und Nachteile auf einen Blick
Traditionell wurden viele Softwaresysteme als einzelne geschlossene Einheit, als so genannter Monolith entwickelt. Dem gegenüber stehen moderne, verteilte Architekturen, bei denen die Software in getrennten Softwarekomponenten entwickelt und veröffentlicht wird. Häufig stellt sich daher die Frage, ob und wann die Auftrennung einer monolithischen Anwendung sinnvoll ist. Dieser Artikel beleuchtet diese Fragestellung, stellt die Vor- und Nachteile der einzelnen Ansätze gegenüber und liefert Entscheidungshilfen für eine etwaige Migration.
Was ist eine monolithische Architektur?
In der Softwareentwicklung bezeichnet die monolithische Architektur eine Art der Softwarestruktur, die aus einem einzelnen, autarken Programm besteht, das alle Geschäftsabläufe erledigt. Die Anwendung wird in einer großen Codebasis entwickelt und zusammen kompiliert, getestet, ausgeliefert und ausgeführt. Die Bestandteile einer monolithischen Anwendung sind in der Regel fest miteinander verknüpft und teilen sich Systemressourcen. Monolithische Architekturen sind sozusagen die All-in-one-Lösung in der Softwareentwicklung.
Die Implementierung einer monolithischen Architektur ist in der Regel simpel, da die Bestandteile homogen aufgebaut sind und die Kommunikation zwischen Komponenten über einfache Funktionsaufrufe unkompliziert ist.
Die Vorteile einer monolithischen Architektur
Im Vergleich Monolith vs. Microservice sind Entwicklungssetup und Veröffentlichung bei einer monolithischen Architektur einfacher, da nur eine Anwendung ausgeführt werden muss.
Höhere Performance, weil alle Aufrufe innerhalb des gleichen Systemprozesses erfolgen.
Die Recherche von Fehlern ist simpler als in verteilten Systemen, da ein Aufruf nicht über Prozessgrenzen hinweg verfolgt werden muss.
Die Nachteile einer monolithischen Architektur
Es muss immer die gesamte Anwendung veröffentlicht werden. Dadurch ist die Wirkungsradius von Deployments größer. Das hat Einfluss auf Qualitätssicherungsprozesse, erfordert gegebenenfalls die Abstimmung von Wartungsfenstern und führt häufig zu weniger, aber größeren Updates.
Skalierung ist nur für die gesamte Anwendung möglich, auch wenn nur ein bestimmter Geschäftsprozess von höherer Last betroffen ist.
Einschränkung in der Flexibilität, da die Anwendung einen einzelnen Technologiestack verwendet, der auch für sämtliche, neue Funktionalitäten genutzt werden muss.
Verteilte Systemarchitekturen sind oft schon in sich modularisiert, da dies durch die technischen Grenzen der Systemkomponenten erzwungen ist. In monolithischen Anwendungen ist es ungleich wichtiger, den Code in beherrschbare, möglichst unabhängige Einheiten zu unterteilen. Erfolgt das nicht, kann die Komplexität so weit ansteigen, dass Änderungen schwierig und fehleranfällig werden.
Was bedeutet Microservice-Architektur?
Im Gegensatz zur monolithischen Architektur besteht eine Microservice-Architektur aus einer Vielzahl kleiner, autonomer Services. Jeder Microservice erfüllt eine bestimmte Geschäftsfunktion und kann unabhängig entwickelt werden. Die Services kommunizieren dabei über ein leichtgewichtiges Protokoll wie REST, gRPC und/oder eventbasiert mit den Schnittstellen der anderen Services.
Ein einzelner Microservice kann in jeder Programmiersprache geschrieben sein, die besten Werkzeuge für seine Aufgabe verwenden und über eigene Datenbanken und Infrastrukturkomponenten verfügen. Darüber hinaus sind Microservices so gestaltet, dass sie als eigenständige Anwendungen ausgeführt werden können, was bedeutet, dass sie einfach neu gestartet, aktualisiert oder skaliert werden können, ohne dass andere Services beeinträchtigt werden.
Eine Erweiterung der Microservice-Architektur, stellt die so genannte Microfrontend Architekur dar, bei der der Modularisierungsgedanke auf die Frontends der Anwendung erweitert wird, wobei sich die Microservice-Architektur selbst standardmäßig auf das Backend der Applikation bezieht.
Die Vorteile einer Microservice-Architektur
Die Entwicklung einzelner Services lässt sich gut auf unabhängig arbeitende Teams aufteilen. Neue Funktionalitäten können in separaten Services ergänzt werden, ohne das Gesamtsystem zu beeinflussen. Auf diese Weise werden agile Entwicklungsprozesse gefördert und Entwicklungszyklen verkürzt.
Microservices können unabhängig, basierend auf dem jeweiligen Lastprofil, skaliert werden.
Im Vergleich Monolith vs. Microservice können Microservices individuell veröffentlicht werden – auch parallel zu älteren Versionen. Das führt zu einer verringerten Tragweite von Deployments und damit zu kleineren, häufigeren Releases – bis hin zu Continuous Deployment Szenarien.
Durch Auftrennung in einzelne Services sind Microservice-basierte Anwendungen oft besser modularisiert und die einzelnen Einheiten leichter wartbar.
Weil einzelne Geschäftsfunktionalitäten als Schnittstellen zur Verfügung stehen, können diese auch zum Aufbau gänzlich neuer Lösungen basierend auf den existierenden Funktionalitäten verwendet oder für die Anbindung externer Systeme genutzt werden.
Die Flexibilität bei der Technologieauswahl ist größer, da der Technologiestack für jeden Microservice individuell bestimmt werden kann. So können die passendsten, modernen Frameworks und Infrastrukturkomponenten für den jeweiligen Service ausgewählt werden.
Die Nachteile einer Microservice-Architektur
Das Recherchieren und Nachvollziehen von Fehlern ist in verteilten Systemen komplexer, weil eine Anfrage für einen Geschäftsprozess potenziell viele Services durchläuft. Standardisierung bei Themen wie Logging und Telemetrie, sowie die durchgehende Verwendung von Korrelations-IDs schaffen dabei Abhilfe.
Die Performance von Microservice-basierten Anwendungen kann durch den zusätzlichen Overhead für die Kommunikation zwischen den Services problematisch werden. Techniken wie die Verwendung von asynchronen Serviceaufrufen oder Events sowie der Einsatz von Caching helfen bei der Bewältigung von Performanceproblemen.
Im Vergleich Monolith vs. Microservice ist das Entwicklungssetup einer Microservice-Architektur aufwändiger, da es notwendig werden kann, mehrere Services für den Entwicklungsworkflow zu starten, oder die Aufrufe entsprechend ersetzt werden müssen (z. B. durch Mocking).
Es entsteht erhöhter Kommunikationsbedarf zum Beispiel bei Updates, da die Anforderungen eines Geschäftsprozesses gegebenenfalls von mehreren Teams bearbeitet werden müssen und das Deployment der voneinander abhängigen Services koordiniert werden muss.
Weniger Standardisierung, da die Services gegebenenfalls unterschiedliche Technologiestacks verwenden. Das kann zu einer heterogeneren Technologielandschaft führen, die beherrscht, gewartet und aktualisiert werden muss.
Es ist anspruchsvoller die Datenkonsistenz im Gesamtsystem zu wahren, da Aufrufe über Servicegrenzen im Fehlerfall nicht einfach durch Transaktionen zurückgerollt werden können. Es empfiehlt sich der Einsatz von Mechanismen wie dem Outbox oder dem Saga Pattern. Diese erfordern aber zusätzlichen Entwicklungsaufwand.
Wann sollten Unternehmen einen Monolithen migrieren?
Auf die Frage, ob und wann man einen Monolithen zu einer Microservice-Architektur migrieren sollte, gibt es keine eindeutige Antwort. Man sollte sicherlich nicht nur deswegen migrieren, um danach eine Microservice-Architektur zu haben.
Stattdessen sollte es in den dargestellten Nachteilen monolithischer Architektur und/oder in den Vorteilen von Microservice-Architekturen Punkte geben, die eine entscheidende Verbesserung des Status Quo für das betrachtete System bedeuten.
Beispiele:
Die Entwicklung am aktuellen Monolithen ist sehr komplex und fehlerträchtig geworden. Dadurch ist die Geschwindigkeit, in der Anpassungen vorgenommen werden können, stark eingeschränkt. Die Komplexität soll reduziert werden und die Arbeit zukünftig auf mehrere Teams verteilt werden.
Der Monolith bildet einige Geschäftsprozesse ab, bei denen Performance besonders wichtig ist. Die Performanceanforderungen werden aktuell nicht erfüllt und die horizontalen oder vertikalen Skalierungsmöglichkeiten sind erschöpft oder zu kostspielig. Die einzelnen betroffenen Geschäftsfunktionen sollen daher extrahiert und individuell skaliert werden.
Das monolithische System basiert auf einem Legacy Framework. Eine komplette Migration ist nicht ad-hoc machbar. Stattdessen sollen sich häufig ändernde und neue Komponenten direkt mit modernen Frameworks umgesetzt werden können, um von deren technologischen Vorteilen zu profitieren. Schrittweise soll danach der Monolith migriert werden.
Von Monolith zu Microservice: Vorgehensweise bei der Migration
1. Microservices identifizieren:
Ermitteln der verschiedenen Geschäftsbereiche oder Funktionen, die in Ihrem monolithischen System existieren, und definieren, wie diese in einzelne Microservices unterteilt werden können. Hierfür eignen sich Methodiken aus dem Domain-Driven-Design (DDD), um Bounded Contexts zu ermitteln.
2. Erstellung einer Roadmap:
Der Übergang von einem Monolithen zu Microservices kann ein aufwändiger Prozess sein. Es ist daher wichtig, eine detaillierte Roadmap zu erstellen, wann welcher Service extrahiert werden soll. Die Prioritäten sollten sich dabei nach dem erwarteten zusätzlichen Geschäftswert nach der Migration ausrichten.
3. Querschnittsaspekte verproben:
Erstellung eines technischen Durchstichs, bei Scrum oft als Spike bezeichnet, zur Konzeption von:
Microservice-Kommunikation
Definition wie die Microservices in welchen Szenarien miteinander kommunizieren und welche Protokolle und Komponenten dafür verwendet werden sollen. Das kann über Schnittstellenaufrufe – direkt oder über ein API-Gateway – und/oder über Messaging unter Verwendung eines MessageBus erfolgen.Runtime und Entwicklungsumgebung
Festlegung wie die Microservices zur Entwicklungszeit ausgeführt und in Produktion betrieben werden sollen. Das kann beispielsweise die Verwendung von Cloud-Diensten und anderen Technologien wie Docker, Kubernetes und Dapr umfassen.Observability sicherstellen
Standardisierung für die Themen Logging und Telemetrie, beispielsweise durch Nutzung von OpenTelemetry und einer entsprechenden Aggregations- und Visualisierungslösung.
4. Graduelle Migration ermöglichen:
Die Migration von Microservices sollte stets so geplant werden, dass erste Microservices von Anfang an neben dem Monolithen existieren und ihre Aufgaben übernehmen können, statt das Projekt erst nach Migration des kompletten Monolithen mit einem Big Bang auszurollen. Dazu eignet sich die Verwendung des Strangler Fig Patterns. So wie sich die namensgebenden Würgefeige um ihren Wirtsbaum herumlegt und diesen nach und nach erdrückt, werden die Microservices nach und nach um den Monolithen aufgebaut, bis dieser komplett ersetzt und damit obsolet ist. Dazu ist es notwendig, eine technische Möglichkeit für die Koexistenz von Monolith und Microservice zu schaffen. Das kann anhängig vom Aufbau des Bestandsystems über Routing-Regeln z. B. in einem API-Gateway realisiert werden. Alternativ kann die Verwendung von Wrappern wie Adapter/Proxies oder Fassaden hilfreich sein.
Microservice vs. Monolith: Fazit
Dieser Artikel bietet einen umfassenden Überblick über die Unterschiede zwischen Monolith vs. Microservice, einschließlich deren Vorteile und Nachteile. Die Entscheidung, einen Monolithen in Microservices zu migrieren, sollte sich an konkreten Problemen oder Verbesserungsmöglichkeiten orientieren, die durch einen Wechsel , adressiert werden können.
Die kompetenten Expertinnen und Experten bei Arvato Systems haben langjährige Erfahrung in der Migration von Applikationen und Applikationslandschaften. Sie bieten Unternehmen unterschiedlicher Branchen Unterstützung – durch Architekturreviews der bestehenden Applikationen, Planung der Modernisierungsinitiativen und bei der Umsetzung dieser durch skalierbare Kapazitäten.