Ein Thema, welches mich aktuell stark beschäftig sind Microservices. Bereits vor einiges Zeit eher zufälligerweise ein Projekt nach diesem Prinzip designed, setzt das Thema sich nun in der breiten Masse durch.
Ich möchte meine Gedanken und Erfahrung dazu hier bloggen.
Wann ist ein Service Micro
Kurz: wenn sie eigenständig lauffähig sind, eine spezialisierte Aufgabe erfüllen und von einem kleinen Team gepflegt werden können, am Besten einer 1-Mann-Armee.
Ja, die Aussage klingt erstmal gewagt, trifft es aber ziemlich genau.
Im Internet findet man zahlreiche Diskussionen und Aussagen darüber, was ein Microservices ist. Jedoch lassen sich einerseits fixe Vorgaben wie „nicht mehr als 100 Zeilen Code“ nicht mit der Realität vereinbaren, andererseits ist ein Service (man kann es auch Programm nennen) das gleich mehrere Funktionen bietet (z.B. Benutzerverwaltung und Bestellsystem) eben auch nicht mehr „Micro“. Letzteres wäre eher ein Produkt aus mehreren Services. Ein Microservice sollte also den Anspruch haben, möglichst atomar zu sein.
Services als Micro richtig einordnen
Als Indikatorhilfe für einen Microservice kann man folgende Fragen nehmen:
- Ist eine abgegrenzte Funktionalität abgebildet?
- Läuft das Gesamtsystem weiter, wenn diese Funktionalität ausfällt?
- Kann der Service eigenständig getestet werden?
- Kann der Service aktualisiert werden, ohne Impact auf das Gesamtsystem?
- Ist der gefühlte Einarbeitungsaufwand in die Codebase niedrig?
Genau genommen haben Punkt 2 und 4 natürlich Einfluss auf das Ökosystem, und zwar dann, wenn der Services angefragt wird aber nicht zur Verfügung steht und im anderen Fall, wenn er fehlerhafte Daten liefert.
In beiden Fällen ist das restliche System aber weiter verfügbar, der User bekommt im Besten Fall bis zur Behebung des Problems nichts von dem „Ausfall“ mit.
Der 5. Punkt ist natürlich eher subjektiver Natur, aber auch nicht zu unterschätzen. Der gesunde Menschenverstand ist eben auch ein zuverlässiger Indikator, erfordert aber eine objektive Sichtweise. Tipp: spätestens wenn man das Gefühl hat, eine eierlegende Wollmilschsau vor sich zu haben, ist es definitv kein Microservice mehr.
Just another Hype?
Eigentlich ist der Architekturansatz nicht wirklich etwas neues. Während die Idee der Microservices (MSA) bereits 2005 geprägt wurde, hat die Umsetzung in der Breite eigentlich erst vor kurzem begonnen. Oftmals wird sie als temporäre Erscheinung betrachtet („schon wieder so ein allheilsbringes Buzzword), oder es wird darauf verwiesen, bereits eine service-orientierte Architektur (SOA) einzusetzen.
Beides sind erstmal legitime Standpunkte, denn zum einen ist der Markt ja tatsächlich überschwemmt von unzähligen Technologien und Buzzwords, zum anderen besteht tatsächlich eine SOA eben auch aus Services.
Man sollte sich dabei eine MSA als nächste Evolutionsstufe einer SOA vorstellen, oder eine höhere Granularität. Während eine Anwendung eben in nach SOA Prinzipien entwickelt wurde, hat eine MSA einfach den Anspruch, sehr spezialisierte Funktionen gekapselt bereitzustellen. Also kann man demnach sagen, dass MSA eine SOA ist, aber eine SOA nicht unbedingt eine MSA – letzteres könnte aber durchaus der Fall sein.
Wir sehen also, dass MSA den SOA Ansatz konsequent weitertreibt und bei genauerer Betrachtung auch Sinn macht, wenn eine Anwendung hochverfügbar, -skalierbar und dabei auch noch leicht wartbar bleiben soll.
Vorteile
Da dies ein Blog über MSA ist, möchte ich hier die Vorteile hervorheben (die Schattenseite finden weiter unten Erwähnung).
Wenn man sich mit dem Thema befasst, hat man bei bestehenden Anwendung meistens schon gewisse Grenzen kennengelernt und sucht nach Optimierungsmöglichkeiten. Das könnte sein:
- Verfügbarkeit: Ein verunglücktes Deployment hat die Produktivumgebung lahm gelegt.
- Performance: Die Anwendung wird langsam, da zu viele Anfragen bearbeitet werden müssen.
- Weiterentwicklung: Verbesserungen an einem Modul führen zum Re-Deployment des gesamten Systems.
- Wartung: Downtimes wegen OS Updates führen zu Engpässen oder der Code selber ist zu komplex geworden.
Die Überlegungen führen bei den Betrachtungen ganz automatisch dazu, dass man das System verteilt, am besten auf möglichst atomarer Ebene, so dass die Artefakte einzelnd austauschbar wären. Ja, und bestimmte Funktionen sollten bei Bedarf mehr Rechenpower erhalten. Am Besten temporär, denn Infrastruktur kostet Geld.
Man kommt also in Bereiche des Cloud Computing, Big Data und DevOps. Alles spannende Themen, denen man dabei auf jeden Fall begegnet.
Aber des Pudels Kern ist, dass Anwendung selber auch die Vorraussetzungen erfüllt, um in einer solchen Landschaft sinnvoll laufen zu können. Auch ohne Cloud usw hat man von einer solchen Architektur bereits Vorteile. Und das sind die der Microservices:
- Hohe Verfügbarkeit
- gute Skalierbarkeit
- Services können hinzugefügt werden
- Gut Wartbar
Nicht der Einfachheit halber habe ich hier die Gegenteile der obigen Liste aufgeführt. Es sind schlicht die Vorteile, die man sich an Bord holen kann.
Kann !! Weiter unten erfahren wir etwas mehr über die Kehrseiten.
Monolith vs Microservices
Das Gegenstück zur MSA ist eine Monolithische Architektur. Wie der Name schon sagt, handelt es sich hierbei um einen Klotz-Code. Alle Funktionen einer Anwendung sind in einem Artefakt enthalten, z.B. einem WAR. Sicherlich sind in dem Artefakt auch Services in Form von Business Objekten, EJB usw. enthalten. Dies sind aber keine Services im Sinne von MSA, sondern einfach interne Dienstfunktionen – und meistens auch nicht von außen aufrufbar. Selbst wenn letzteres der Fall sein sollte, dann wäre dies ein Beispiel für SOA – eine Anwendung die Services bereitstellt (typischerweise Webservices). Diese werden wiederum von anderen Anwendungen benutzt.
Auf den Monolithen kann man jetzt exemplarisch die 5-Punkte Liste von oben anwenden – was wir jetzt einfach mal tun:
Punkt 1 ist klar: der Monolith enthält alle Funktionen die die Anwendung für ihre Umsetzung benötigt. Also: nein.
Punkt 2: Ist der Monolith eine Software im Gesamtsystem, dann könnten andere Komponenten durchaus weiter funktionieren. Der User bekommt vielleicht garnicht mit, dass der Monolith ausgefallen ist. Dann wäre die Antwort ja. Da aber der Monolith sicher viele Funktionen realisiert, ist die Wahrscheinlichkeit dafür eher gering. Wir sehen hier also, dass selbst in einer SOA die Antwort auf diese Frage „Nein“ wäre.
Punkt 3: Na klar kann ein Service eines Monoliths eigenständig getestet werden. Es ist aber immer notwendig das Gesamtsystem auszuliefern. In der Regel weiß man auch nicht, wie die Verzahnungen Systemintern so sind. Realistisch betrachtet ist die Antwort hierbei auch „Nein“.
Punkt 4: Nehmen wir an, an unserem Monolithen wurde die Funktion für Kundenauswertungen verbessert. Um das System produktiv zu setzen kann man mutig davon ausgehen, dass alle anderen Funktionen ja nicht nochmal getestet werden müssen, da dort ja nichts geändert wurde. In der Realität ist aber ein vollständiger Regressionstest dringend notwendig, denn man kann nicht davor ausgehen, dass es keine Seiteneffekte gibt. Auch wenn nach besten Wissen und Gewissen alle Abhängigkeiten bedacht wurden, die Wahrscheinlichkeit ist recht hoch. Mutig wäre es also, diese Frage mit „Ja“ zu beantworten. Natürlich stellt die MSA hierfür kein Allheilmittel dar, denn auch hier muss getestet werden und Seiteneffekte sind auch hier möglich.
Punkt 5: Jeder der eine umfangreiche moderne Anwendung kennt, weiß die Antwort: die lautet meistens „Nein“.
Und nun?
Martin Fowler schrieb einst (http://martinfowler.com/):
If you can’t build a monolith, what makes you think microservices are the answer?
Da muss man ihm recht geben. MSA gehört nur in die Hände von erfahrenen Entwickler, die bereits gute Monolithen erstellt haben! Beipackzettel beachten: „Zu Risiken und Nebenwirkungen fragen Sie ihren Berater oder Architekten“ 🙂
Es muss also genau überlegt werden, ob man seine Anwendung in eine MSA überführt.
Und wenn ja, dann stellt sich die Frage, wie man das umsetzt. Es müssen nicht unbedingt gleich Cloud Technologien wie Docker Swarm, Cloud Foundry usw involviert sein. Auch ein loser Schwarm von Service-Exponierenden-Artefakten kann ein MSA Verband bilden. Dabei können Loadbalancer für Ausfallsicherheit sorgen.
Die Bezeichnung „loser Schwarm“ und „Service-Exponierenden-Artefakten“ verdeutlicht hierbei die Unabhängigkeit von Technologie.
Neben technologischen Aspekten gibt es auch eine ganze Reihe von anderen Implikationen:
- Der Abstimmungsaufwand wird steigen. Nicht nur bei der Definition der Architektur selber, sondern auch bei der Kommunikation der Teams.
- Themen wie Logging und Monitoring müssen vollständig betrachtet werden – denn was bringt eine tolle MSA, wenn hinterher ein Fehler nur schwer nachvollzogen werden kann.
- Security Issues sind ein heißes Eisen. Die Services müssen also evt. abgesichert werden, möglicherweise reicht eine reine Transportverschlüsselung nicht aus.
- Die Systemlandschaft wird komplexer. Abhängig von den eingesetzten Tools gelangt mehr Komplexität ins Projekt – Technologien wie Docker, Cloud Foundry, Puppet, Zookeeper usw benötigen auch Know How.
- Services alleine ergeben kein brauchbares Programm. Es wird auch immer ein Workflow benötigt, eine Einheit, die den ganzen Haufen steuert. Ob man diese in externe Orchestrierungs Engines auslagert, oder dies selber als Microservice realisiert oder dies sogar implizit im Kommunikationsprotokoll (welches auch ausgewertet werden muss) verankert, muss bedacht werden.
Die Liste kann sicher noch fortgesetzt werden. Es muss klar sein, dass da wo Licht ist, auch Schatten nicht fern ist.
Es bleibt spannend, wie MSAs in der Breite umgesetzt werden, ich bin mir sicher, dass insgesamt sehr unterschiedliche Herangehensweise umgesetzt werden. Möglicherweise kristallisiert sich auch etwas heraus, was als DER Standard angesehen wird.
Damit beschließe ich den Blog für heute. Im nächsten Beitrag zu dem Thema möchte ich näher auf konkrete Technologien eingehen und wie man aus einem Monolithen eine MSA macht.
Feedback, Anmerkungen und Reaktionen sind herzlich willkommen