Ist eine Microservice-Architektur Stand der Technik (Teil 3 - Gegenüberstellung)

Die (objektive und nachvollziehbare) Bestimmung, ob eine Microservice-Architektur für ein bestimmtes Projekt geeignet ist, ist aufwändig. Es lassen sich aber einige der Vorteile den Nachteilen gegenüberstellen, wodurch sich für einen Großteil aller Projekte eine allgemeine Aussage ableiten lässt. Eine meist einfach zu machende Einordnung einer Software bezüglich der im Folgenden genannten Vor- und Nachteile bzw. im folgenden Blogpost aufgezählten Merkmale sollte reichen, um sicherzustellen, dass eine Microservice-Architektur für die jeweilige Software geeignet/ungeeignet ist.1
Allgemeine Gegenüberstellung der Vor- und Nachteile einer Microservice-Architektur gegenüber einem Modulithen2
- Unterschiedliche Skalierung vs. Performance: Wie beschrieben ist eine Microservice-Archtektur in unterschiedlichen Teilen (Microservices) unterschiedlich skalierbar, während ein Modulith nur in seiner Gesamtheit skalierbar ist. Andererseits aber ist ein Modulith performanter, da er keine Aufrufe über Prozessor/Nodegrenzen benötigt.
Während Performance zweifelsohne ein Problembereich vieler Applikationen ist, so ist nicht klar, was für Vorteile eine unterschiedliche Skalierung bringt. Organisatorisch ist unterschiedliche Skalierung sicherlich ein Mehraufwand. Vergleicht man die Preise von Cloud-Anbietern so erkennt man, dass die selbe Gesamtperformance mit mehr Nodes auch etwas teurer ist, als mit weniger Nodes. Unterschiedliche und gleichartige Skalierung sind beide effektiv, da sie zu einer Skalierung führen. Was aber, wenn Teile einer Applikation (auch beim besten Willen)3 nicht skalierbar sind und derart viel Systemressourcen in Anspruch nehmen, dass sie andere Teile behindern? Dann könnte der Rest nur bei unterschiedlicher Skalierung dennoch skalieren.
→ In den allermeisten Fällen ist der Performanceverlust durch Microservices ein weitaus größerer Nachteil als der nur in Ausnahmefällen tatsächlich existierende Vorteil der unterschiedlichen Skalierbarkeit. - Unabhängigkeit vs. Organisationsaufwand: Die Möglichkeit Microservices unabhängig von anderen zu entwickeln, testen, deployen und warten und ebenso die Unabhängigkeit hinsichtlich der verwendeten Sprachen, Tools, Technologien und Versionen je Service kann zu für das jeweilige Service optimalen (effizienten/effektiven) Lösung führen. Aber es es kann ebenso auch zu einem Wildwuchs an Architekturen, Technologie-Stacks, Versionen, beziehungsweise auch UI-, Protokollierungs-, Reporting- oder Überwachungsstandards führen. Beides ist nur mit gewissem Koordinations- und Organisationsaufwand erreichbar. Erfahrungsgemäß steigt der diesbezügliche Aufwand exponentiell mit der Anzahl der Teams bzw. in diesem Fall mit der Anzahl der Microservices bzw. Unterschiede zwischen den Microservices. Bei großen Applikationen mit vielen Teams und Microservices wird man das nur mit strikten, automatisiert sichergestellten und oft ungeliebten Regeln effizient und effektiv erreichen können.
→ Unabhängigkeit ist nur dann ein Vorteil, wenn sie zu optimaleren Teillösungen und nicht zu einem Wildwuchs führt und der Vorteil den dafür benötigte Koordinations- und Organisationsaufwand kompensiert. - Codierungs- vs. Entwicklungsproduktivität: Microservices können zweifelsohne auf Grund der eben beschriebenen Möglichkeiten der Unabhängigkeit produktiver geschrieben werden als gleich große Module eines Modulithen. Die Vermeidung von Domain-Reuse aber auch die Notwendigkeit des Schreibens von Code zur Kommunikation, teilweise unter Einsatz komplexer Microservice-Patterns, führen aber insgesamt zu mehr Code. Das wird - auch bei Vermeidung von Wildwuchs - durch die oben beschriebenen Auswirkungen der Unabhängigkeit der Teams noch deutlich verstärkt.
→ Auch wenn die einzelnen Microservices effizenter als Module entwickelt werden können, führt eine Microservice-Architektur zu mehr und komplexeren Code und potentiell in Summe geringerer Entwicklungseffizienz. - Testproduktivität: Testarten, die sich auf ein einziges Microservice beschränken lassen, sind bei Microservices effizienter zu entwickeln und durchzuführen. Microservice-übergreifende Testarten sind auf Grund des aufwändiger bereitzustellenden (auf einzelnen Entwickler/Testrechnern potentiell gar nicht bereitstellbaren) Gesamtsystems weniger effizient.4 Um eine akzeptable Fehlerdichte zu erreichen, wird man aber in den meisten Situationen nicht umhin kommen, sämtliche Testarten durchzuführen. Bei sicherer Software (also z.B. solcher mit gemäß DSGVO schützenswerten Daten) und auf jeden Fall bei Software, wo Fehler Menschenleben kosten könnten, sowie Standard- oder COTS-Software wird dies zu hohen Testaufwänden führen.
→ Software, die auf Grund der Fehlerauswirkungen eine geringe Fehlerdichte aufweisen muss, wird sich in einer Microservice-Architektur nicht effizient testen lassen. - Deployment: Wie geschrieben, kann man eine Software bei einer Microservice-Architektur potentiell in Teilen und somit sukzessive deployen5, wärend man einen Modulithen nur gesamthaft deployen kann. Letzteres ist bei einem Modulithen dafür auf Grund der nicht vorhandenen Abhängigkeiten wieder einfacher. Standzeiten lassen sich bei beiden Architekturen vermeiden, Continuous Delivery funktioniert ebenfalls mit Modulithen.
→ Teildeployments sind nur dann ein Vorteil, wenn sie auch fachlich benötigt werden. Ansonsten halten sich die Vor- und Nachteile beim Deployment in etwar die Waage - Architektur: Die architekturelle Aufteilung und die Beziehungen zwischen den Komponenten ist bei einer Microservice-Architektur sichergestellt. Um das ebenso bei einem Modulithen sicherzustellen, benötigt es diesbezügliche Technologien.6 Dafür aber ist eine Microservice-Architektur auch starrer, da architekturelle Änderungen ungleich aufwändiger sind als bei einem Modulithen.
→ Die Einhaltung der Architektur lässt sich mit beiden Architekturen sicherstellen, bei einer sich potentiell änderbaren Aufteilung der Komponenten ist aber eine Microservice-Architektur im Nachteil.
Wie man erkennen kann, kommt es auf die spezifischen Anforderungen eines Projektes an, ob eine Microservice-Architektur effektiver / effizienter / ineffizienter / ineffektiv ist. Im nächsten Blogartikel werde ich die Merkmale einer Software herausarbeiten, die gegeben sein müssen, um mit Fug und Recht behaupten zu können, dass eine Microservice-Architektur (bzw. ein Modulith) für die gegenständliche Software bestmöglich geeignet und somit der Stand der Technik ist.
Fazit: Die Gegenüberstellung der Vor- und Nachteile zeigt, in welchen Situationen eine Microservice-Architektur effizienter als ein Modulith sein könnte. So wie es aussieht, sind das nur wenige.
1. Unter "geeignet" wird hier verstanden, dass die Architektur die Ziele der Software bestmöglich (d.h. effizient und effektiv) unterstützt. Nicht die Ziele der Entwickler "will was neues ausprobieren" oder die von Toolherstellern, Beratern, Architekten oder sonstwem. ↩
2. Wie schon im letzten Blogpost dargelegt wird in beiden Fällen eine bestmöglichst umgesetzte Architektur verglichen. Darum auch der Begriff "Modulith" = ein gut strukturierter Monolith = das was immer das Ziel einer monolithischen Architektur war. ↩
3. Beispielsweise sind komplexe, NP-schwere Algorithmen oft nicht skalierbar. Nimmt so ein Algorithmus alle CPUs eines Systems in Anspruch, so sinkt auch die Performance der davon unabhängigen Teile des Systems. ↩
4. Teilweise auch deshalb (mehr aber getrieben durch Continuous Delivery) wird bei Microservice-Architekturen ein Verzicht der letzteren Testarten zugunsten als Alternativen vorgestellten Techniken wie canary deployment und auto-rollback.. Ob diese Techniken effizienter/effektiver als Microservice-übergreifende Testarten sind, ist ein anderes Thema und wird hier nicht betrachtet. ↩
5. wenn die Änderungen keine Schnittstellen betreffen und es auch sonst keine technischen/fachlichen oder zeitlichen Abhängigkeiten zwischen den Microservices gibt, die ein gleichzeitiges oder in bestimmter Reihenfolge durchzuführendes Deployment benötigen. ↩
6. Im Java Umfeld wären das beispielsweise ArchUnit oder spring-modulith. ↩
Kommentare
Kommentar veröffentlichen
Wenn du auf meinem Blog kommentierst, werden die von dir eingegebenen Formulardaten (und unter Umständen auch weitere personenbezogene Daten, wie z. B. deine IP-Adresse) an Google-Server übermittelt. Mehr Infos dazu findest du in der Datenschutzerklärung von Google (https://policies.google.com/privacy).