Kolumne: Stropek as a Service

Sind Microservices ein Irrweg und elegante Monolithen die Lösung?
Keine Kommentare

Meine Twitter-Timeline läuft im Moment über wegen der Diskussionen, ob Microservices nicht ein großer Irrtum waren. Man hört Lobgesänge auf elegante Monolithen. Microservices seien im Betrieb viel zu komplex. Die lose Kopplung der Services führe zu enormem Kommunikationsaufwand und damit schlechter Performance. Getrennte Datenspeicher für jeden Microservice seien der pure Horror angesichts der zigfach duplizierten Datenbestände und der daher notwendigen Datensynchronisation.

Ich habe in dieser Kolumne schon oft über verschiedene Aspekte geschrieben, wie Microservices umgesetzt werden und welche Werkzeuge Public Clouds wie Microsoft Azure für ihre Umsetzung beinhalten. Angesichts der immer lauter werdenden Diskussion möchte ich diesmal das Warum in dem Mittelpunkt stellen.

Kundenorientierung

Meiner Ansicht nach müssen moderne Entwicklungsteams Kundenorientierung ganz weit oben auf ihre Prioritätenliste setzen. Es hilft nichts, wenn Software wunderbar strukturiert und technisch auf dem neuesten Stand ist, aber nicht das tut, was die Benutzer verlangen. Als Entwicklungsteams dürfen wir beschäftigt sein nicht mit produktiv sein verwechseln. Es ist leicht, uns mit technischen Raffinessen selbst zu beschäftigen. Produktiv sind wir nur, wenn aus dem investierten Entwicklungsaufwand auch eine konkrete Verbesserung aus Kundensicht resultiert. Benutzern ist es vollkommen egal, ob die Software in der genormten Testumgebung gute Performance zeigt, für sie zählt die Performance im Echtbetrieb unter den Rahmenbedingungen, die bei ihnen vorzufinden sind.

Microservices helfen aus meiner Sicht, eine Entwicklungsorganisation aufzubauen, die diese Kundenorientierung widerspiegelt. Der Grund ist, dass Microservices nicht nach technischen Kriterien abgegrenzt werden, sondern nach inhaltlichen. Man spricht je Microservice vom Bounded Context, einem fachlich abgegrenzten Teilbereich, in dem wichtige Geschäftsprozesse ablaufen. Die Gliederung von Microservices orientiert sich an den Denkmustern und Prozessen der Kunden, nicht an technischen Konzepten aus der Softwareentwicklung. Microservices wie Datenbankservice, Berichtsgenerator oder Lokalisierungsservice sind Negativbeispiele. Sie repräsentieren technische Cross-Cutting Concerns, und als Entwicklungsteam tendieren wir dazu, sie in zentrale Module oder Services auszugliedern, um Codeduplizierung zu vermeiden.

Benutzer denken aber anders. Ihnen sind ihre Geschäftsprozesse wichtig, nicht deren softwaretechnische Umsetzung. Sie haben zu Recht kein Verständnis dafür, wenn wir als Entwicklungsteam sagen, dass eine bestimmte, für sie wichtige Funktion von uns gerade nicht umsetzbar ist und dass sie erst mit einem anderen Team (z. B. zentral entwickelter Berichtsgenerator-Service) ausmachen sollen, dass dort die Grundlagen für die Umsetzung ihres funktionalen Wunsches geschaffen werden müssen. Diese Situation ist für Kunden aus mehreren Gründen nicht zufriedenstellend. Erstens bekommen sie die notwendige Funktion nicht oder nur mit Verzögerung. Zweitens müssen sie sich mit dem technischen Aufbau der Software in einer Tiefe auseinandersetzen, die sie eigentlich nicht interessiert. Drittens müssen sie sich mit mehreren Teams absprechen und Koordinationsaufgaben übernehmen, die nicht in ihren Aufgabenbereich fallen.

Eingeschworenes Team

Setzt man auf Microservices-Teams, hat eine Domänenexpertin fast immer genau ein Entwicklungsteam, mit dem sie zu tun hat. Dieses Team hat die Aufgabe, für die Benutzer seines Bounded Contexts gute Lösungen anzubieten. Es ist, was technische Entscheidungen betrifft, weitgehend autonom und kann sich Werkzeuge suchen, die helfen, die inhaltlichen Anforderungen in seinem Bereich gut zu lösen. Genauso wichtig wie die passende Auswahl an Werkzeugen ist auch die passende Weiterentwicklungsgeschwindigkeit. Manche Microservices profitieren von neuen, technischen Entwicklungen und manche weniger. Autonome Teams können ihre technische Strategie an die Anforderungen in ihrem inhaltlichen Tätigkeitsbereich anpassen.

Noch wichtiger als technische Fragen ist aber die Tatsache, dass das Entwicklungsteam mit seinen Kunden zu einem eingeschworenen Team zusammenwächst und man an einem Strang zieht.

Vielfalt, nicht Wildwuchs

Wenn ich das oben erwähnte Argument in Microservices-Workshops bringe, kommen immer die gleichen Gegenargumente. Das erste ist die Angst vor Wildwuchs. Jedes Team verwendet andere Werkzeuge und Plattformen und aus Unternehmenssicht hat man das nicht mehr im Griff. Was übersehen wird, ist, dass die autonomen Teams in der Praxis natürlich nicht vollkommene Freiheit haben. Sie müssen sich innerhalb vorgegebener Grenzen (aka Enterprise Alignment) bewegen. Diese Grenzen sind aber viel weiter gesteckt als in der verstaubten, auf Richtlinien und Standardisierung getrimmten Softwareentwicklungsorganisation. Mein – nicht ganz ernstgemeintes, aber einprägsames – Bild ist: Entwickler werden von Legebatteriehühnern zu Freilandhühnern. Sie können nicht uneingeschränkt tun, was sie wollen, haben aber weit mehr Freiheiten als bisher, um auf die ihnen gestellten Anforderungen reagieren zu können.

Das zweite Gegenargument ist die Angst davor, das Rad unzählige Male zu erfinden. Man will doch Synergieeffekte nutzen und die Lernerfahrungen von einem Team in alle anderen tragen. Dafür braucht es Standardisierung und teamübergreifend wiederverwendete Module, oder nicht? Dieses Argument ist richtig, in einer idealen Welt gibt es nichts dagegen zu sagen. In der Realität spricht aber eine Sache dagegen: Wiederverwendung bedeutet Abhängigkeiten, und das geht oft nach hinten los.

Auflösen von Abhängigkeiten

Wenn man sich in einer monolithischen Software auf einen Technologiestandard einigt und viele Module von vielen Teams wiederverwenden lässt, bedeutet das, dass die Weiterentwicklung der Software gleichförmig passieren muss. Es ist schwierig für ein Team, vorzupreschen und beispielsweise von einer neuen Plattformversion frühzeitig zu profitieren. Es hat manchmal katastrophale Konsequenzen, wenn ein Modul, das eine zentrale Stellung in einem Monolithen einnimmt, verwaist und die Vorteile der Codewiederverwendung sich plötzlich in eine Handbremse verwandeln, die zu Softwarealterung führt. Schrittweise, grundlegende technische Wechsel sind in einem Monolithen schwierig, da alle sich nahezu gleichzeitig verändern müssen.

In kleinen Projekten, bei denen die Gesamtverantwortung vielleicht auch in der Hand einer Person liegt, ist es machbar, die harmonische Weiterentwicklung über längere Zeit sicherzustellen. Sobald mehrere Teams im Spiel sind, die sich unterschiedlich weiterentwickeln müssen oder wollen, wird aus dem Monolithen schnell ein Frankenstein-Monster, bei dem Technologien und Module zusammengeschraubt werden, die nicht gut zusammenpassen.

Im Bereich der Datenbank helfen Microservices ebenfalls, Abhängigkeiten loszuwerden. Wenn eine Fachexpertin zum Microservice-Team kommt und sich Änderungen wünscht, möchten wir nicht erst mit zig anderen Teams notwendige DB-Änderungen abstimmen müssen. Ist dies notwendig, führt das Veto eines Teams, mit dem man sich Tabellen teilt und das gerade keine Zeit hat, seinen Code anzupassen, zu einer Blockade dem Kunden gegenüber. In der Praxis entstehen so ineffiziente und aufwendige Lösungen, weil die Funktionen trotzdem umgesetzt werden und man mit Kompromissen versucht, um diese Blockaden herum zu entwickeln. Hat jeder Microservice seinen eigenen Datenspeicher, wird die notwendige Abstimmungsarbeit weniger.

Microservices haben Nachteile

Kein Zweifel, Microservices haben Nachteile, z. B:

  • Code wird oft dupliziert oder mehrfach entwickelt.

  • Daten sind zum Teil redundant und müssen über Service-Grenzen hinaus synchronisiert werden.

  • Heterogene Basistechnologien bedeuten einen gewissen Mehraufwand im Betrieb.

  • Ein Service-Aufruf über das Netzwerk ist langsamer und fehleranfälliger als ein Methodenaufruf im selben Prozess.

  • Im Monolith kann der Compiler auf Inkonsistenzen zur Übersetzungszeit hinweisen, die bei lose gekoppelten Microservices zu Laufzeitfehlern führen.

Es wäre falsch, Microservices als Silver Bullet für die Strukturierung von Softwarelösungen darzustellen. Als Organisation muss man die oben genannten Nachteile von Microservices gegenüber ihren Vorteilen abwägen. Die perfekte Lösung gibt es nicht.

Langfristiger Blick über Technik hinaus

Wenn die Nachteile der Microservices-Architektur stark zum Tragen kommen, sollte man nicht gleich das Architekturmuster verteufeln. Vielleicht hat man es mit dem „Micro“ übertrieben und Dinge, die inhaltlich zusammengehören, auseinandergerissen. In diesem Fall geht es nicht darum, die an sich gute Idee der Microservices über Bord zu werfen, sondern die Umsetzung zu hinterfragen und anzupassen. Vielleicht fehlen der Organisation aber auch die richtigen Werkzeuge für das Arbeiten mit Microservices. Logging, Monitoring und Telemetrie spielen beispielsweise eine enorm wichtige Rolle und ohne professionelle Lösung in diesem Bereich ist der Betrieb von Microservices frustrierend.

Meiner Erfahrung nach haben Microservices, wenn sie nicht zu feingranular sind, langfristig Vorteile. In dieser Kolumne bin ich insbesondere auf Kundenorientierung und das Vermeiden technischer und organisatorischer Abhängigkeiten eingegangen. Ersteres hilft einem Entwicklungsteam, die Wertschöpfung aus Kundensicht zu steigern, und Letzteres, die langfristige Investitionssicherheit zu erhöhen. Von mir gibt es eine klare Empfehlung für Microservices, zumindest für mittelgroße und große Softwareprojekte in der Cloud.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu:
X
- Gib Deinen Standort ein -
- or -