BED-Con 2018: Warum Microservices scheitern

Berlin Brandenburger Tor

Die BED-Con findet jährlich in Berlin statt und deckt traditionell ein breites Spektrum an Themen ab. Dazu gehört die Vorstellung aktueller Technologien aus den Bereichen Java, JavaScript, DevOps, Software-Architektur, Microservices, DDD oder Datenbanken. Viele Vorträge basieren auf Erfahrung aus dem Entwicklungsalltag oder privaten Projekten und haben daher einen praktischen Bezug. Auch finden sich Vorträge zu Soft-Skill Themen wieder, welche das Angebot abrunden. Dank der breiten Themenfächerung findet sich jeder schnell in einem Talk wieder, der ihn interessiert.

 

Zu meinem persönlichen Highlight der diesjährigen BED-Con gehört der Beitrag von Eberhard Wolff. In seinem Vortrag "Warum Microservices scheitern" befasste er sich mit typischen Gründen warum Lösungen auf Microservicebasis häufig nicht zum gewünschten Erfolg führen.

 

Microservices bringen im ersten Schritt eine höhere Komplexität der Anwendung mit sich, da in der Regel weitere Technologien und schnell auch Themen des Betriebs mit berücksichtigt werden müssen. Ein dermaßen verteiltes System bringt somit neue Herausforderungen aus verschiedenen Themengebieten und Wissen um die betreffenden Umsysteme mit sich. Schnell findet man sich tief im Thema DevOps wieder. Sie versprechen auf der anderen Seite auch viele Vorteile, wenn man sich an einige Grundregeln hält. Gründe für das Scheitern finden sich demnach zu meist auf technischer oder organisatorischer Ebene.

 

Technische Gründe fürs Scheitern

Deployment Monolithen

In einem Deployment Monolithen werden alle Microservices zur gleichen Zeit deployt. Der Benefit der Unabhängigkeit verpufft. Was unter dem Strich bleibt ist die durch den Einsatz von Microservices erzeugte höhere Komplexität. Eine häufige Ursache dafür ist z.B. ein geteiltes Datenmodell entweder auf Datenbank Ebene oder auf Entitätsebene. An dieser Stelle wurde die Software nicht vertikal sondern horizontal geschnitten und damit eine Persistenz Schicht geschaffen von der alle Microservices abhängen. Ein Ripple-Effekt setzt ein, sobald sich in dieser Schicht Änderungen ergeben.

 

Abhilfe schafft hier die Trennung der Datenhaltung und eine Entkopplung des Modells. Dadurch kann jeder Microservice für sich eine Datenhaltung schaffen die das und nur das umfasst, was für ihn selbst auch relevant ist. Auch das Naming der Felder kann sich an seiner eigenen Domäne orientieren und muss sich nicht an künstlichen generischen Bezeichnern orientieren, welche der Verständlichkeit aus verschiedenen Blickrichtungen geschuldet ist. Redundanzen sind in diesem Szenario grundsätzlich erlaubt, wenn sie der Entkoppelung der Dienste zuträglich ist.

 

Zentralisiertes Datenmodell

Viele Services teilen sich eine Schnittstelle eines Services. Dieser muss dafür ggf. ein generischeres Datenmodell bereitstellen, damit alle Konsumenten damit arbeiten können. Was wie eine bequeme Abkürzung aussieht, um mehreren Services gerecht werden zu können bindet in der Praxis diese Services durch die geteilte Schnittstelle aneinander. Die Lösung dafür ist es für jeden Service eine eigene Schnittstelle zu verwenden. Damit haben zwei Services jeweils immer nur einen Vertrag miteinander und brauchen bei Änderungen keine dritten Berücksichtigen. Das gilt auch für eventbasierte Systeme. Auch diese sollten nicht geteilt werden.

Bedcon

Organisatorische Gründe

Betrieb

Der hauseigene Betrieb oder der des Kunden stellt sich quer. Vorteile von Microservices werden nicht gesehen oder es fehlt schlichtweg an Know-How für die benötigten Umsysteme oder den Betrieb der zugehörigen Infrastruktur. Keine Microservices einzusetzen ist hier der bessere Ansatz. Derartige Probleme lassen sich aber in der Regel vorab aufdecken.

 

Mode

"Microservices sind gerade ziemlich in also sollten wir die verwenden." Warum das keine gute Idee ist, braucht hoffentlich nicht weiter erläutert werden.

 

Sonstige Gründe

Technologie-Fetisch

Die DevOps Bewegung aber auch der Microservice Hype haben eine Vielzahl neuer Technologien entstehen lassen: Eine verlockender wie die nächste. Jede verspricht Lösungen für potentielle Probleme welchen man auf seiner Reise in die Microservice Welt begegnen kann. Obwohl es inzwischen viele großartige Technologien in diesem Dunstkreis gibt, ist es keine gute Idee alle auf ein Mal direkt in sein neues Projekt mit einzubinden. Häufig löst man damit technologische Probleme die man (noch) gar nicht hat und überfordert sich mit neuem anstatt konkrete Features umzusetzen die jemandem einen Mehrwert bieten. Wenn man schon mit so vielen neuen Umsystemen arbeitet ist es übrigens besonders wichtig auch eine neue Programmiersprache zu verwenden. Und ein neues Framework.

 

Eberhard Wolff nannte in seinem Vortrag noch weitere Gründe wie Synchrone Aufrufe bei denen sich die Latenzen akkumulieren oder eine schlechte Code Struktur welche durch den Einsatz von Microservices zu einer schlechten Code Struktur mit Microservices aufgewertet würden.

 

Wie immer in der Software-Architektur geht es um das Finden des richtigen Trade-Offs. Es gibt keine eindeutig beste Lösung. Welchen Preis man für welche Vorzüge bereit ist zu zahlen, muss von Fall zu Fall abgewogen werden. Diese Regel gilt tatsächlich für alle Fälle, oder um es mit den Worten von Jochen Mader zu sagen: "A good developer is like a werewolf: Afraid of silver bullets."