Microservices Pragmatisch

December 16th, 2019 · 5 mins read

Pragmatische Ansätze aus dem Projektalltag für die erfolgreiche und sichere Umsetzung von Microservices-Architekturen.
Lukasz Juszczyk

Lukasz Juszczyk

Article Series
Microservices - pragmatisch, praktisch, gut
Wie baut man Microservices? Eigentlich sollte die schier unendliche Anzahl an Technologien und Best-Practices, die uns zur Verfügung stehen, unser Leben erleichtern. Doch es ist nicht leicht, daraus die Passenden auszuwählen. Zu groß ist die Auswahl und auch die Angst, dass man zum Falschen greift. Das führt oft dazu, dass man sich strikt daran orientiert, wie es die Microservice-Protagonisten machen und dabei sich zu selten die Frage stellt, wie gut das alles im eigenen Unternehmen funktionieren wird. In dieser Artikelserie werden wir uns das Thema Microservices aus genau dieser Perspektive ansehen. Wir werden vorherrschende Ansätze hinterfragen und schauen, ob es nicht auch einen simplen Weg gibt, wie man Microservices einführen und die Architektur graduell wachsen lassen kann.

Part 1

Microservices Pragmatisch - Eine Einführung

Die Einleitung zur Artikelserie über pragmatische Ansätze bei Microservices-Architekturen. Mit einem kritischen Blick auf gängige Praktiken, enttarnen wir versteckte Falltüren und erarbeiten uns somit eine solide Grundlage um Microservices pragmatisch zu unserem Vorteil einsetzen zu können.

...

Pragmatische Ansätze bei Microservices-Architekturen

Wen man heutzutage jemanden fragt, wie moderne (Enterprise-)Software-Entwicklung aussieht, dann wird man mit sehr hoher Wahrscheinlichkeit folgende Punkte aufgezählt bekommen:

  • Natürlich wird agil gearbeitet, bevorzugt nach SCRUM.
  • Bei der Backend-Architektur sind Microservices mittlerweile Common-Sense, Monoliten gelten als veraltet.
  • Das Frontend ist eine Single-Page-Application, die per REST mit dem Backend kommuniziert.
  • Und betrieben wird alles in einer PaaS, entweder in der Cloud oder notfalls doch on-premise.
  • ( ... )

Dieses Bild ist relativ verbreitet, das zeigt uns auch ein Blick in Fachzeitschriften und Konferenzen, wo diese Themen seit Jahren prominenter Bestandteil der Agenda sind. Dies hat auch auf viele Unternehmen abgefärbt, die sich als Ziel gesetzt haben, ihre komplette Software-Entwicklung in diese Richtung zu transformieren, weil sie sich davon höhere Effizienz versprechen.

Cargo Cults

Die Beweggründe für den Wunsch nach dieser Transformation klingen allerdings, wenn man sie genau hinterfragt, oft dogmatisch. So als wenn all die aufgezählten Punkte ausschließlich Vorteile hätten und es somit nur folgerichtig wäre, sich dorthin entwickeln zu wollen. Nur leider gibt es Silver-Bullets, wie Architekturstile, Technologien und Prozesse, die ausschließlich Vorteile haben, nicht wirklich. Je nach Produkt welches man baut und den Bedingungen, unter welchen man im Unternehmen Software entwickelt, ergeben manche Ansätze durchaus Sinn. Manche nur in abgewandelter Form. Und manche gar nicht. Im Gegenteil, sie richten massiven Schaden an, wenn man sie falsch anwendet. Der Vergleich mit Cargo-Cults1, der oft verendet wird, um dieses Phänomen zu beschreiben, trifft den Nagel auf den Kopf.

Figure 1: Der Cargo-Kult bezeichnet das Nachahmen von Verhalten, ohne den dahinter liegenden Sinn zu verstehen.
Figure 1: Der Cargo-Kult bezeichnet das Nachahmen von Verhalten, ohne den dahinter liegenden Sinn zu verstehen.

Pragmatismus

Was hilft dagegen? Hinterfragen von Prozessen und Entscheidungen. Eine genaue Analyse von Vor- und Nachteilen. Eine grundsätzliche Offenheit für Veränderungen. Aber auch eine gesunde Resistenz gegen Hypes. Kurz gesagt: Pragmatismus.

Diese Artikelserie ist als allgemeines Plädoyer für mehr Pragmatismus in der Software-Entwicklung zu verstehen. Dass wir pragmatischer in unserer Entscheidungsfindung werden und uns Fragen stellen, weshalb wir etwas Neues einführen, welches bestehende Problem wir damit eigentlich lösen und ob das dann auch tatsächlich zum Unternehmen passt. Nur weil Netflix auf Microservices schwört und Spotify mit seinem Vorgehensmodell effizient ist, bedeutet das noch nicht automatisch, dass man deren Ansätze 1:1 übernehmen kann und ähnliche Effekte erzielen wird.

Wir werden uns in den nächsten Beiträgen gezielt das Thema Microservices ansehen und einen vom Hype befreiten Blick auf Theorie und Praxis werfen.

Microservices - immer eine gute Idee?

Eine Definition, was Microservices sind, werden wir überspringen. Schnell im Web gesucht, findet man hunderte Definitionen, aus denen man sich seine Favorisierte auswählen darf. Ein vernünftiger Ansatz, wo anstatt einer Definition gemeinsame Charakteristika herangezogen werden, kommt von Martin Fowler2.

Pro und Contra

Aber was verspricht man sich im Allgemeinen von Microservices? Richtig angewandt, bieten sie zweifelsfrei viele Vorteile:

  1. Sie sind das Resultat einer konsequent durchgezogenen Modularisierung, was allgemein als Qualitätsmerkmal einer Systemarchitektur gesehen werden kann.
  2. Die Komplexität eines Microservice ist schon alleine aufgrund der Dimensionen wesentlich kleiner und deswegen sind diese leichter zu verstehen.
  3. Sie sind voneinander physisch entkoppelt und können unabhängig deployt und aktualisiert werden, ohne dass man das Gesamtsystem dafür neu deployen muss.
  4. Aufgrund der physikalischen Trennung sind microservice-basierte Systeme resilienter, da z.B. ein Speicherleck oder Überlastung nur ein Service beinträchtigt und nicht das ganze System.
  5. Die Skalierbarkeit vom Gesamtsystem wird verbessert, da die Last in der Regel nicht auf alle Services gleich verteilt ist und man somit nur die stark beanspruchten hochskalieren muss.
  6. Microservices werden von nur einem Team entwickelt, womit die Freiheit erhöht und das Konfliktpotential reduziert wird.
  7. Jedes Service kann in der für seinen Anwendungsfall optimalen Sprache und Technologie umgesetzt werden. Technologie-Upgrades werden leichter umsetzbar, da sich diese nur auf einzelne Services beschränken.
  8. Durch klar definierte Schnittstellen ist eine Wiederverwendbarkeit der Services gegeben.

Dem gegenübergestellt werden in der Regel eine Handvoll Nachteile, die vor allem hervorheben, dass man an vielen Stellen mit höheren Aufwänden rechnen muss:

  1. Integrationstests sind im Setup wesentlich aufwendiger, weil diese nun mehrere Services involvieren, die in der richtigen Version instanziert werden müssen.
  2. Logging wird aufwendiger, da die Logs von mehreren Services aggregiert werden müssen um den Kontext eines Fehlers zu rekonstruieren.
  3. Feingranulares Monitoring im Betrieb ist Pflicht, um Ausfälle bzw. Überlastungen von einzelnen Services erkennen und dem entgegensteuern zu können.
  4. Die Komplexität des Systems wird nur von den einzelnen Services zum "Integrationslayer" verschoben, seien dies nun andere (higher-level) Services, eine Prozessengine oder ein Message-Bus/-Broker.

Es gibt jedoch auch zahlreiche versteckte Herausforderungen, welche sich erst richtig bemerkbar machen, wenn man bereits in einer microservices-typischen Sackgasse gelandet ist:

  1. Die an sich sinnvolle Regel, dass jedes Service die Hohheit über die eigene Daten(bank) hat und diese niemals mit anderen Services direkt teilen sollte, hat als Konsequenz dass es wesentlich schwieriger wird, Daten aus mehreren Quellen zu aggregieren (keine direkten Joins möglich) oder Updates transaktional zu machen.
  2. Refactorings werden aufwendiger. Zwar nicht die innerhalb eines einzelnen Services, aber wenn man zur Erkenntnis kommt, dass der Serviceschnitt nicht optimal ist und man gerne Services zusammenführen/aufteilen/transformieren will, dann ist die Komplexität dieses notwendigen Refactorings wesentlich höher, da Logik und vor allem Daten zwischen zwei de-facto unabhängigen Modulen migriert werden müssen. (Sorgt für schönen Nervenkitzel in der Produktion!)
  3. Die Kompatibilität zwischen Schnittstellen und Clients muss gewährleistet sein. Das bedeutet, dass Schnittstellen immer abwärtskompatibel sein müssen oder, dass bei manchmal unvermeidlichen Breaking Changes, ein neues Service erschaffen werden muss.
  4. Das Management der Versionierung von Services, inklusive automatisiertem Check, ob Abwärtskompatibilität gewährleistet ist oder wie lange welche Versionen von welchen Services in Verwendung sind, ist nicht trivial.
  5. Der Betrieb wird wesentlich komplexer, da nun eine Vielzahl von Services in der korrekten Version deployt, aktualisiert, überwacht und dynamisch skaliert werden muss.
  6. Durch die Aufteilung eines Systems in mehrere Services, entstehen zumindest auf Transportebene neue Fehlerquellen, denen man mit Relisienzpatterns entgegenwirken muss.

Fazit

Prinzipiell könnte man die Liste an Vorteilen, Nachteilen und Falltüren, die es zu beachten gibt, noch weiter fortführen. Gewiss hat jedes Team, welches Microservices anwendet eigene positive und negative Erfahrungen gemacht, die es dieser Diskussion beisteuern könnte. Die Quintessenz ist jedoch, dass die Entscheidung, Microservices zu machen, kein No-Brainer ist und gründlich durchdacht werden sollte. Nicht alles, was bei Netflix, Amazon, etc. gut funktioniert, wird automatisch auch im eigenen Unternehmen erfolgreich einsetzbar sein. Was auch - vor allem im Enterprise-Umfeld - oft übersehen wird, ist dass eine erfolgreiche Microservice-Architektur nicht nur die Technik umfasst, sondern dass die gesamte Organisation der Unternehmens darauf ausgerichtet sein muss, um auch wirklich die Vorteile ausspielen zu können.

In dieser Artikelserie, werden wir uns diverse Aspekte daraus genauer ansehen. Am Anfang werden wir uns passenderweise das Bootstrapping eines Microservice-Systems ansehen und die Frage beleuchten, ob es sinnvoll ist dieses bereits von Tag eins an zu modularisieren, oder ob es auch andere Wege gibt.


  1. Die Cargo-Kult-Wissenschaft: https://de.wikipedia.org/wiki/Cargo-Kult-Wissenschaft
  2. Martin Fowler über Microservices bei der GOTO 2014: https://www.youtube.com/watch?v=wgdBVIX9ifA
Lukasz Juszczyk
TwitterLinkedinXing
Lukasz ist Co-Founder und Software-Entwickler/-Architekt bei SQUER. Sein Fokus liegt auf Enterprise-Architekturen, die er als PhD-Student auf der TU Wien erforscht und danach hauptsächlich im Bereich der Financial Industries entwickelt hat. Technologisch fühlt er sich am stärksten der Java-Welt verbunden und hat ein Faible für alternative JVM-Sprachen, wie Kotlin, Scala und Groovy.

Vienna

Wir sind stolzer Host einer Konferenz rund ums Thema Softwareentwicklung.