Monolith vs. Microservices Part 10
Start with a good design
Bleibt zum Abschluss unserer Blogserie noch die Frage offen, hatte nun Martin Fowler oder Stefan Tilkov recht: „Monolith first“, „Don’t start with a monolith“? Unsere Antwort: Starte mit einem guten Design!
Zusammenfassung
Nach einem Jahr treffen wir die beiden wieder und erkundigen uns nach dem aktuellen Stand. Das Start-up hat mittlerweile acht Entwicklerteams, die mehrere Microservices betreuen. Moni und Michi sind froh, von Anfang an auf Microservices gesetzt zu haben. Sie konnten so die unterschiedlichen Anforderungen an die verschiedenen Teile der Software optimal bedienen und durch unabhängige Entwicklung die Services in der notwendigen Geschwindigkeit erweitern und vorantreiben. Durch die beiden Microservices zu Beginn konnten die Entwicklerteams Erfahrungen rund um die Heraus-forderungen eines verteilten Systems sammeln. Mittlerweile sind abwärtskompatible Schnittstellen-änderungen und resiliente Service-Implementierungen Tagesgeschäft in den Entwicklerteams geworden.
In dieser Artikelserie wurden verschiedene Themengebiete behandelt, die für eine Entscheidung für oder gegen Microservices wichtig sind. Wir haben aufgezeigt, welche Einflüsse die Teamaufstellung auf die Architektur hat und dass eine vertikale Teamaufstellung (Trennung der Teams nach Fachlichkeit) der Way-to-go ist. Um zu den Elite-Performern zu gehören, spielt nicht nur die technische Architektur, sondern auch die Unternehmenskultur und das agile Vorgehensmodell eine wichtige Rolle. Kurze Feedbackzyklen und kleinere Arbeitspakete helfen genauso auf dem Weg zum Elite-Performer wie eine modular aufgebaute, leicht deploy- und testbare Architektur.
Ferner wurde aufgezeigt, dass ein sauber strukturierter Modulith als eine ernsthafte Alternative zu einer Microservice-Architektur betrachtet werden muss. Allein die Entscheidung auf eine Microservice-Architektur zu setzen, hilft noch lange nicht für ein erfolgreiches Softwareprojekt oder gutes IT-Design. Vielmehr verbergen sich hinter den vielen Vorteilen einer Microservice-Architektur eine Menge Herausforderungen, die verteilte Systeme mit sich bringen. Schnittstellen werden auf einmal zu Sollbruchstellen innerhalb des Systems und müssen über Resilience-Pattern abgesichert werden. Bei der Datenhaltung und -replikation kann es zu Inkonsistenzen kommen, die beachtet werden müssen. Und es kommen ganz neue Arten von Fehlern ins Spiel: Das klassische Denken „wenn x dann y“ funktioniert in verteilten Systemen nicht mehr. Hier heißt es stattdessen: „wenn x dann vielleicht y“. Dieses Umdenken erfordert einen großen Aufwand, sowohl beim Design und Entwicklung der Architektur als auch in der Entwicklung.
Warum diesen ganzen Aufwand dann also betreiben? Es gibt einige sinnvolle Anwendungsfälle von Microservice-Architekturen, bei denen auch ein Modulith an seine Grenzen kommt:
- Das System erfordert eine hohe Skalierbarkeit einzelner Teile. Skalierbarkeit wird, wie in der Artikelserie beschrieben, aber oft überbewertet und ist für viele Anwendungsfälle gar nicht relevant. Diese Anforderung haben eigentlich nur sogenannte Hyperscaler wie Amazon oder Netflix.
- Es gibt unterschiedliche nicht-funktionale Anforderungen für verschiedene Teile der Anwendung. Ein Teil muss zum Beispiel sehr sicher sein, kann dafür längere Antwortzeiten haben. Ein anderer Teil muss hochverfügbar, aber weniger sicher sein.
- Man möchte die einzelnen Teile einer Anwendung unabhängig voneinander entwickeln (in unabhängigen Teams) und unabhängig voneinander deployen. Bis zu einem gewissen Grad funktioniert das aber auch im Modulith!
Nachdem wir so viel über nicht-funktionale Anforderungen gesprochen haben – welchen Einfluss haben eigentlich funktionale Anforderungen auf die Entscheidung, ob Microservices oder nicht? Nun, es gibt einen Grund, warum wir in dieser Artikelserie kaum auf funktionale Anforderungen eingegangen sind – sie spielen nämlich keine Rolle bei der Entscheidung für oder gegen Microservices. Denn egal, ob man Software als Modulith oder mit einer Microservice-Architektur umsetzt: Es ist wichtig, dass die Module oder Services richtig geschnitten sind. Das betrifft aber beide Herangehensweisen und ist kein Vor- oder Nachteil für das ein oder andere. Für den richtigen Schnitt hilft uns der Werkzeugkasten, den uns Eric Evans mit „Domain Driven Design“ zur Verfügung gestellt hat.
Zum Schluss der Serie bleibt nur noch eine Frage offen: Wie einigen sich Moni und Michi?
Bezüglich der Teamaufstellung sind sich beide einig geworden, sie möchten vertikale Teams mit klaren fachlichen Verantwortungen in den Teams. Nachdem das Start-up noch nicht allzu viele Entwickler:innen hat, starten sie mit zwei Teams. Die beiden Teams entwickeln je einen größeren Microservice. Die jeweiligen Services sind aber modular aufgebaut – schon mit dem Hintergedanken, sie später gegebenenfalls weiter zu zerlegen. Während sich ein Team um den Bestellprozess und die Produktpflege kümmert, implementiert das andere Team den Service zur Routenoptimierung und Schnittstelle zu Lieferanten. Der Fokus für den MVP liegt aber erst mal auf dem Bestellprozess, sodass dort mehr Entwicklerkapazitäten vorhanden sein sollen.