Monolith vs. Microservices Part 6: Was schützt vor einem (verteilten) Big Ball of Mud?
BettercallPaul
BettercallPaul

// //
Lesedauer: 4 Minuten

Monolith vs. Microservices Part 6

Was schützt vor einem (verteilten) Big Ball of Mud?


Um Qualität zu sichern, müssen Qualitätsziele und damit Ziele bezüglich des IT-Design festgelegt werden. Sobald die Ziele festgelegt wurden, können einige davon automatisiert geprüft werden. Dennoch entstehen gerade bei Monolithen immer wieder Big Ball of Mud-Architekturen. Oft liest man davon, dass der Einsatz von Microservices zu besserem Design führt und ein Big Ball of Mud mit Microservices vermieden wird. Moni und Michi (die Protagonist:innen unserer Blogserie) stolpern bei ihren Überlegungen zur Restaurant-App natürlich auch über das Thema Qualitätssicherung.

Zusammenfassung

Einige Qualitätsziele können über Metriken geprüft und gesichert werden, die die Anwendung – egal, ob als Modulith oder als Microservice – bereitstellt. Design- und Architekturentscheidungen können auf unterschiedlichen Ebenen sichergestellt werden: Tools wie SonarQube zur statischen Code-Analyse oder ArchUnit zur Prüfung von Zugriffsregeln helfen bei der Sicherstellung der Qualität auf Code-Ebene in einer Anwendung (ein Monolith oder ein Microservice). Für Microservices geht das aber nicht: Hier muss manuell geprüft werden, dass ein Service nur das aufruft, was er tatsächlich braucht.

Generell führt allein die Verwendung von Microservices nicht automatisch zu gutem Design. 

Simon Brown sagte einmal: „If you can’t build a well-structured monolith, what makes you think microservices is the answer?“ (Zitat aus: https://plainoldobjects.com/2016/03/01/thoughts-on-if-you-cant-build-a-well-structured-monolith-what-makes-you-think-microservices-is-the-answer/)

Qualitätssicherung

Moni: „Wir müssen uns noch Gedanken über Design-Richtlinien machen und Qualitätsziele definieren.“

Michi: „Die Aufgabe übernehmen wir am besten gemeinsam. Es wird übergreifende Richtlinien und Ziele geben, aber auch spezifische für die Module beziehungsweise Services.“

Moni: „Wunderbar. Viele Ziele können über Metriken automatisiert geprüft werden. Aber wie verhindern wir, dass der Code zu einem Wirrwarr wird?“

Michi: „Die Verwendung von Microservices bietet einen gewissen Schutz vor Wirrwarr. Ein Zugriff auf Funktionalität eines fremden Microservices, die nicht über eine Schnittstelle bereitgestellt ist, ist unmöglich.“

Moni und Michi diskutieren, wie Design-Richtlinien und Qualitätsziele definiert und anschließend abgesichert werden können. Michi spricht davon, dass zwischen übergreifenden und modul-/service-spezifischen Richtlinien unterschieden werden muss. Dieser Ansatz entspricht der Unterscheidung zwischen Macro- und Micro-Architekturentscheidungen, wie sie bei den Independent Systems Architecture Principles (https://isa-principles.org/index.html) genannt werden.

Modul-/Serviceübergreifende Entscheidungen sind zum Beispiel:

  • Schnitt der Module
  • Kommunikation zwischen Modulen
  • Authentifizierung
  • Format der Log-Meldungen
  • Format für Monitoring/Tracing

Modul-/Servicespezifische Entscheidungen sind unter anderem:

  • Architektur innerhalb eines Moduls
  • Autorisierung
  • Eingesetzte Bibliotheken

Übergreifende Entscheidungen wollen Moni und Michi gemeinsam für die Restaurant-App treffen. Die spezifischen Entscheidungen würden sie den jeweiligen Teams überlassen und in ihrer Architektenrolle nur beratend tätig werden.

Einige dieser Architekturentscheidungen können automatisiert geprüft werden. Zum Beispiel kann mittels ArchUnit auf Unit-Test Ebene geprüft werden, ob Zugriffsregeln von Modulen oder Schichten verletzt werden. Das funktioniert aber logischerweise nur für Monolithen oder einen Microservice. Damit kann nicht sichergestellt werden, dass ein Microservice auf einen anderen zugreift, auf den er nicht zugreifen darf.  

Alle Architekturentscheidungen dienen der Erreichung der festgelegten Qualitätsziele. Auch die Erreichung der Qualitätsziele (z. B. dass die Anwendung zu 95% verfügbar sein muss oder Antworten nur 200ms dauern dürfen) können automatisiert über Metriken geprüft werden. Dazu müssen die Module oder Services natürlich entsprechende Metriken im definierten Format bereitstellen. Die bereitgestellten Daten können zum Beispiel mit Grafana und Prometheus ausgewertet und damit einige nicht-funktionale Anforderungen im Live-Betrieb überwacht werden.

Das zweite Thema, das Moni und Michi im Kontext der Qualitätssicherung diskutieren, ist die Vermeidung eines Big Ball of Mud. Für Monolithen wurde gerade schon ein möglicher Ansatz erläutert: Die Regeln für Zugriffe auf Module, Komponenten & Schichten können in Regeln für ArchUnit gegossen werden und dann automatisiert geprüft werden. Das erfordert initial Aufwand, sorgt aber für eine saubere Struktur der Anwendung, die nicht so leicht umgangen werden kann.

Michi bringt als Argument, dass Microservices einen gewissen Schutz vor Tangling bieten. Während Entwickler:innen innerhalb eines Modulithen theoretisch auf die ganze Funktionalität eines fremden Moduls zugreifen können, können Microservices nur auf fremde Funktionalität zugreifen, die über die entsprechenden Schnittstellen bereitgestellt werden. Allerdings bedeutet das nicht, dass Microservices vor schlechtem Design und hoher Kopplung schützen! Auch bei einer Microservice-Architektur kann durch schlechten Schnitt und hohe Kopplung zwischen Microservices ein Big Ball of Mud entstehen – mit dem Unterschied, dass jeder Aufruf zwischen Services ein Aufruf über das Netzwerk ist und damit weitere Spielarten von Fehlern auftreten können. Details zu den Fehlern gibt es im Artikel zum Thema „Betreibbarkeit“. Damit entsteht im schlimmsten Fall ein verteilter Big Ball of Mud.

Wer keinen sauberen Monolithen designen und implementieren kann, wird keinen Mehrwert daraus ziehen, dieses Design und diese Struktur als Microservice-Architektur zu implementieren. Denn ein verteilter Big Ball of Mud ist deutlich schlimmer als ein „normaler“ Big Ball of Mud. Bevor man das macht, sollte man lieber Aufwand in gutes Design und gute Strukturierung des Monolithen stecken. Eric Evans und Vaughn Vernon haben uns mit ihren beiden Büchern Domain Driven Design (das blaue Buch) und Implementing Domain Driven Design (das rote Buch) einen Werkzeugkasten für Software-Design an die Hand gegeben – mit sehr vielen guten Ansätzen.