Monolith vs. Microservices …


… oder warum nicht jeder Monolith geschlachtet werden muss. Seit einiger Zeit ist der Hype ungebrochen, jedes monolithische System schnell zu ersetzen und jede Neuentwicklung als Microservice-Architektur zu realisieren (eventuell nicht jedes aber doch eine Vielzahl).

Problem Mensch

Aus meiner Sicht ist eines der Hauptprobleme in der Softwareentwicklung, dass nicht Vorhandensein von (geeigneten) Architekturregeln und deren Durchsetzung. Ob dies durch Fehler in der Entwicklung, mangelndes Know How oder fehlende Ressourcen für die Prüfung der Einhaltung der Architektur verursacht wird, ist nicht relevant. Das Ergebnis ist ein schwer wart- und erweiterbares Softwaresystem. Dieses Ergebnis wird sich unabhängig von der Architektur einstellen. Bevor wir uns also Gedanken um den geeigneten Architekturansatz machen, ist sicherzustellen, dass es überhaupt eine Architektur gibt und diese durch einen QS-Prozess auch abgesichert wird. Schlechte Software wird auch als Microservice nicht besser.

Pro und Kontra

Im Folgenden habe ich einige Pro- und Kontra-Punkte zu Monolithen und Microservices zusammengestellt.

  • In einem Monolithen sind die meisten Refactorings wesentlich einfacher und im Allgemeinen mit wenigen Aktionen in der IDE realisierbar.
  • Reporting, Batchläufe und andere Aktionen, die aus vielen Quellen gespeist werden müssen, sind bei Monolithen deutlich einfacher zu realisieren, da auf die zentralen Informationen des Gesamtsystems zugegriffen werden kann.
  • Monolithen haben interne Abhängigkeiten, die gut erkennbar sind. Bei Microservices wird viel Komplexität in die Netzstruktur verschoben, die schwerer erkenn- und wartbar sind. Probleme von verteilten Systemen (Ausfälle, Verlässlichkeit von Knoten) können bei Monolithen nicht auftreten.
  • Systeminterene Schnittstellen können bei Monolithen einfacher geändert werden. Bei Microservices kommt hier Consumer-driven Contracts (z.B. https://jaxenter.de/microservices-consumer-driven-contract-testing-mit-pact-20574) für die Verbesserung der Situation zum Einsatz.
  • Durch statische Codeanalysen lässt sich bei einem Monolithen die Gesamtarchitektur besser prüfen, als bei Microservices. Insbesondere Gesamtsystemprüfen mit jQAssistant und ähnlichen Tools sind hier einfach automatisierbar. Automatische und manuelle Prüfungen der Architektur sind die Basis für gute Codequalität und damit effizientes Arbeiten an dem Prosukt.
  • Bei dem Thema Konsistenz liegt aus meiner Sicht der Monolith klar vorne. Er hat eine einheitliche Datenbasis, die bei guter Umsetztung die Konsistenz ohne zusätzlichen Aufwand garantiert und im Allgemeinen durch Cluster auch gut skalieren kann. Microservices müssen hier auf Eventual Consistency (Achtung nicht eventuell, sondern letztendlich) setzen (Monolithen könnten dies auch), wenn das Konzept der Trennung nicht durch eine einheitliche DB gebrochen werden soll. Der Preis dafür ist, dass einiges an Code für die Sicherstellung der Konsitenz und ggf. dem manuellen Rollback von verteilten Transaktionen investiert werden muss. Dies sollte man sich genau überlegen, wenn in der Anwendung nicht ein so “einfaches” Modell wie beispielsweise bei Netflix eingesetzt wird. Betriebliche Anwendnung haben im Allgemeinen stark abhängige Daten. Wenn diese nicht mehr konsistent sind, sind die Abläufe gefährdert und alle Folgesystem wie DWHs können nicht korrekt arbeiten.
  • Monolithen in Verbindung mit Architektur- und Toolvorgaben machen es einfach, die Anzahl der verwendeten Technologien zu reduzieren. Die Verwendung von weniger Technologien bedeutet, dass viele Teammitglieder an verschiedenen Stellen mit geringer Einarbeitungszeit eingesetzt werden können. Es ist im Allgemeinen für die Wartbarkeit eben kein Vorteil, wenn jeder Microservice einen eigenen Technologie Stack hat. Dies sollte nur geschehen, wenn es deutliche Vorteile gibt.
  • Bei einem guten Design und guter Umsetzung ist auch ein Monolith modular aufgebaut. Ein gutes Design und Prüfung der Einhaltung hierfür benötigen beide Architekturen.
  • Einige Artikel beschreiben es als Vorteil, dass nicht gelungene Microservices „weggeworfen“ werden können. Bei einem guten, modularen Aufbau eines Monolithen können ebenfalls Teile ausgetauscht werden. Grundsätzlich fördert eine solche Argumentation aber „schlechte“ Software und ich kenne wenige zahlende Kunden, die einer solchen Argumentation überhaupt folgen wollen.
  • Domain-Driven-Design ist in beiden Welten umsetzbar.
  • Achtung bei Microservices, die über Datenbanken integrieren oder die Modelle anderer Services direkt weiterverwenden, da in solchen Fällen kein klarer Bounded Context vorliegt und somit ein Pro von Microservices weniger stark greift.
  • Monolithen haben das Problem, dass die Stabilität eines Moduls, sich auf das ganze System auswirken kann. Abgeschwächt gilt dies auch für Microservices, wenn abhängige Dienste instabil laufen.
  • Die physikalische Verfügbarkeit kann in beiden Fällen durch Replikation (Cluster von Application Servern bzw. einzelner Schichten oder Servicereplikation) erreicht werden. Dies ist bei Microservices deutlich einfacher. Außerdem können Microservices gut „bei Bedarf“ skalieren. Aber auch Monolithen können durch Clusterbildung gut skalieren – nur eben nicht dynamisch.
  • Die Skalierbarkeit der Entwicklerteams ist bei Microsrvices besser, da es weniger Abhängigkeiten in der Codebasis gibt. Andererseits verzögern Schnittstellenabsprachen das Vorgehen, so dass aus meiner Sicht mit guter Qualitätssicherung beide Architekturen in gewissen Maßen skalieren.
  • Microservices neigen zur Codeduplizierung mit all ihren Nachteilen.

Aus meiner Sicht gibt es Anwendungsklassen, bei denen Microservices insbesondere ihren Skalierungsvorteil klar ausspielen können. Gerade im Web-Systemen mit vielen Nutzern und überschaubaren Abläufen funktioniert dies prächtig. Bei vielen sogenannten betrieblichen Anwendungen ist ein gut strukturierter und qualitätsgesicherter Monolith meistens besser für die Zielerreichung. Wenig Komplexität in den Kommunikationsstrukturen erleichtern die Erweiterbarkeit. In vielen Fällen ist es effektiver in Softwarearchitektur und den Abbau technischer Schulden zu investieren, als ein ungeeignetes System in Microservices aufzuteilen. Wir werden sehen was die Zukunft bringt …

Du hast Fragen oder Anmerkungen? Kontakt: arndt@schoenb.de