Autonome Dienste statt unflexibler Dienste-Cluster
Ein monolithisches System setzt sich aus eng integrierten Schichten zusammen, die stark voneinander abhängig sind und zusammen herausgegeben werden müssen. Ein Microservice ist dagegen keine Schicht innerhalb eines monolithischen Systems. Vielmehr handelt es sich um eine eigenständige Geschäftsfunktion, die ihre Dienste über Schnittstellen beliebigen Clients zur Verfügung stellt. Eine Architektur aus Microservices bringt eine modulare Abgrenzung der Dienste.
Microservices sind eine Variante der serviceorientierten Architektur (SOA). Ein System wird damit als Sammlung lose gekoppelter, leichtgewichtiger Dienste strukturiert. Die Dienste können unabhängig voneinander entwickelt und skaliert werden. Microservices kommunizieren über Messages, sind dezentralisiert einsetzbar und können kontinuierlich automatisiert bereitgestellt, d.h. integriert und getestet werden. Microservices haben also einen voneinander unabhängigen Lebenszyklus.
Schichtenmodell Monolith vs. Microservice
Typischerweise ist eine monolithische Anwendung aus drei Schichten aufgebaut:
- Geschäftslogik
- Datenschicht
- Benutzeroberfläche
Microservices bestehen dagegen aus:
- Geschäftslogik
- u.U. Datenschicht
- Programmierschnittstelle
Neukonstruktion statt Wiederverwendung
Es empfiehlt sich nicht, Code für die Microservices aus dem Monolith wiederzuverwenden. Dieser Code enthält gerade die Umgebungsabhängigkeiten, die man bei Microservices nicht hat. Wenn monolithische Dienste nicht auf einem klaren Domänenkonzept basieren, entsprechen auch die dabei genutzten Datenstrukturen nicht den neuen Domänenmodellen.
Wie kann eine monolithische Anwendung aufgebrochen werden?
Die Migration sollte schrittweise Kernfunktionen vom Monolithen entkoppeln, indem Abhängigkeiten vom Monolithen beseitigt werden. Wenn diese Richtlinie befolgt wird, werden stattdessen Abhängigkeiten in umgekehrter Richtung aufgebaut - vom Monolith hin zu den Diensten. Dies ist die gewünschte Abhängigkeitsrichtung.
Für diesen Architekturstil ist die Frage der Abgrenzung zwischen den einzelnen Services zu klären. Jeder Migrationsschritt sollte eine Verbesserung der Codeorganisation bringen. Ein typisches Problem sind Features des Monolithen, die nicht auf einem genau definierten Domänenkonzept basieren, von denen aber viele Funktionen des Monolithen abhängen. Entwickler müssen solche Funktionen identifizieren, sie in genau definierte Domänenkonzepte zerlegen und in autonome Dienste umwandeln.
Ein Beispiel für solch ein problematisches Feature in webbasierten Monolithen ist eine "Session", die eine Vielzahl von Attributen über Domänengrenzen hinweg beinhalten können. Entwickler sollten hier inkrementell Microservices aus der Session-Funktion extrahieren, einen Dienst nach dem anderen.
Frontend-Anwendungen werden schließlich auf die neuen Schnittstellen der Microservices umgeleitet. Verschiedene Anwendungen können dann denselben Microservice nutzen.
"Micronaut" ist ein Beispiel für ein modernes Framework zur Entwicklung einfach testbarer Microservices auf der Java Virtual Machine.
Herausforderungen bei Microservice-Architekturen
Verteilte Architekturen bringen ihre eigene Art von Komplexität mit sich. Bei der Migration müssen der Aufwand und mögliche Nachteile beachten werden:
- Inter-Service-Aufrufe über ein Netzwerk haben höhere Kosten (Latenzen) als Inter-Prozess-Aufrufe in einem monolithischen System.
- Dienste mit verschiedenen Programmiersprachen und Technologien erhöhen die Komplexität.
- Anfragen über mehrere Services hinweg mit jeweils eigenen Interfaces sind schwerer zu verfolgen als in Monolithen.
- Jeder Service muss durch ein Berechtigungssystem abgesichert werden. API Access Controls and Gateways sind für die Sicherheit von Microservices zuständig.
- Der Ausfall eines Microservices sollte kompensiert werden können und nicht dem Gesamtsystem schaden.
- Das Monitoring und Logging wird komplexer.
Jetzt unten für den Newsletter anmelden und keine Taledo-Neuigkeiten verpassen!