Software Engineering

Microservices, ein Vorgehensmodell zur Softwareentwicklung

Der Microservice-Ansatz wird häufig als ein Architekturstil für den Entwurf von verteilten Softwaresystemen gesehen. Er ermöglicht die Implementierung eines Systems durch eine größere Menge von kleinen Diensten (Services). Führt man Unterhaltungen über Microservices werden häufig nur technische Faktoren genannt. Dabei werden andere Bereiche des Microservice-Ansatzes, die Aufteilung der Services, wie die Services entwickelt werden und was für Änderungen in der Team und Firmenstruktur nötig sind, oft außer acht gelassen. Gerade diese Aspekte können jedoch für den Erfolg eines Projektes essentiell sein und charakterisieren den Microservice-Ansatz daher nicht nur als Architekturstil, sondern auch als Vorgehensmodell zur Softwareentwicklung.

Microservices

Der Begriff „Microservice“ hat seit einiger Zeit eine Menge Aufmerksamkeit gewonnen. Der Microservice-Ansatz kann sowohl als ein Architekturstil für den Entwurf von verteilten Software- Systemen, als auch ein Vorgehensmodell zur Softwareentwicklung betrachtet werden. Hinsichtlich der Eigenschaften als Architekturstil sind Microservices ein Ansatz für die Implementierung eines Systems durch eine größere Menge von kleinen Diensten (Services). Die Entwicklung eines Systems nach dem Microservice-Ansatz unterliegt dabei folgenden Prinzipien [1]:

• Evolutionäres Design (Evolutionary Design)
• Strenge Kapselung (Shared Nothing)
• Hohe Fehlertoleranz (Design for Failure)
• Intelligente Dienste und einfache Kommunikation (Smart Endpoints & Dump Pipes)
• Dezentrale Datenhaltung (Decentralized Data Storage)
• Automatisierung der Infrastrutur (Build-, Test- und Deployment-Prozesse)
• Organisation um Geschäftsfunktionen (Business Capabilities)
• Entwicklung von Produkten und keine Durchführung von Projekten (Products not Projects)
• Dezentrale Verwaltung (Decentralized Governance)
• Zerlegung in Komponenten durch Services (Componentization)

Jeder Dienst wird dabei unabhängig ausgeführt (eigener Prozessraum), verwendet seine eigenen Daten (Datenbank) und bietet leichtgewichtige Kommunikationsmechanismen gegenüber anderen Diensten (oft über HTTP oder HTTPS). Die Dienste beinhalten ausschließlich Funktionalitäten, die rund um Geschäftsfunktionen (Business Capability) gruppiert werden können. Sie haben somit einen fachlich stark eingeschränkten Fokus, woraus in der Regel direkt die Grundprinzipien serviceorientierter Architekturen umgesetzt werden, insbesondere werden lose Kopplung, starke Kohäsion und die Trennung unterschiedlicher Belange (Separation of Concerns) erreicht.

Microservices als Vorgehensmodell

Führt man Unterhaltungen über Microservices werden häufig nur technischen Faktoren genannt. Diese decken jedoch nur einen Teil des Microservice-Ansatzes ab. Der andere Teil beschäftigt sich primär mit der Aufteilung der Services, wie ein isolierter Service entwickelt wird oder wie die entwickelnden Teams zusammengestellt werden sollten. Somit wird hier ein starker Fokus auf Eigenschaften eines Vorgehensmodells zur Softwareentwicklung gelegt. Aber wie sollten Services innerhalb einer Mikroservice Architektur geschnitten werden und welche Auswirkung hat das auf die Entwicklerteams?

In monolithischen Architekturen erfolgt die Umsetzung großer Systeme in der Regel durch spezialisierte Teams. Das bedeutet zumeist, dass diese den Schichten der Software-Architektur entsprechend gebildet werden. Daher entstehen im Regelfall spezialisierte Teams je Anwendungsschicht (wie Benutzer-Interface, Middleware und Daten). Die Organisation der Teams wird sich üblicherweise in der System-Architektur widerspiegeln (siehe Abbildung 1). Dieser Sachverhalt ist bereits aus Conways Gesetz bekannt [2]: „Any organization that designs a system … will inevitably produce a design whose structure is a copy of the organization’s communication structure.”

Sobald das System eine gewisse Größe überschritten hat, bedeuten Änderungen der Geschäftslogik (Middleware-Schicht) meistens einen hohen Aufwand, da aufgrund der Organisationsstruktur und selbst bei serviceorientierten Systemen in der Regel viele Abhängigkeiten zwischen den Diensten einer Schicht bestehen.

Im Gegensatz hierzu fokussieren Microservices eine einzige Geschäftsfunktion und nutzen zu deren Umsetzung eine breite technologische Basis (einschließlich der Benutzerschnittstelle, Datenhaltung und externer Kommunikation). Dies bedingt, dass auch die Team-Organisation anders erfolgt. Teams werden typischerweise funktionsübergreifend (cross functional) organisiert, die Team-Mitglieder entstammen unterschiedlichen Aufgabenbereichen (von der Gestaltung der Benutzer-Schnittstelle über die Geschäftslogik und Datenbank bis hin zum Projektmanagement). Das Ziel dieser Zusammenstellung ist, dass jeder Microservice isoliert von einem Team entwickelt werden kann (shared nothing). Das Team selbst kann dabei die eingesetzten Technologien anhand der Anforderungen und vorhandenen Fähigkeiten bestimmen und so die optimale Lösung entwickeln (decentralized governance). In Verbindung mit dem Prinzip des evolutionären Design (evolutionary design) kann ein Team sogar so weit gehen eine komplette Technologien innerhalb eines Mikroservices auszutauschen. Auf Grund der anvisierten Größe eines Microservices ist es ebenfalls möglich, dass ein Team sich dazu entscheiden kann den gesamten Microservice innerhalb einer kurzen Zeit (z.B. einem Sprint) von Grund auf neu zu implementieren.

Produkte und keine Projekte

Das was sich zunächst für Entwickler nach einem wahrgewordenen Traum und für Projektleiter nach einem Albtraum anhört, ist jedoch nur die halbe Wahrheit. Wie so häufig geht mit großer Macht auch eine große Verantwortung einher. An dieser Stelle kommt das Prinzip der Produktentwicklung gegenüber der Projektarbeit (products not projects) zum tragen. In klassischen Strukturen wird Software für gewöhnlich in Projekten erstellt. Für die Laufzeit des Projektes werden Teams mit der Aufgabe eine Software zu implementieren beauftragt. Das Ziel dieser Teams und deren Projektleiter ist es, die Software in gewünschtem Funktionsumfang und Budget fertigzustellen. Bei Erfolg wird die entstandene Software an eine weitere Partei übergeben, welche die, oft undankbare, Aufgabe hat die Software zu betreiben. Da der zweiten Personengruppe selten die Mitglieder der Projektphase angehören, haben diese während des Projektes weniger Anreiz eine stabile und betretbare Software abzuliefern. Der Fokus liegt hier darauf die geforderte Software innerhalb des Budgets zu entwickeln, nicht aber auf dem Betrieb eben jener Software.

Der Microservice-Ansatz behandelt dieses Problem indem ein Team nicht nur für einen begrenzten Zeitraum ein Projekt durchführt, sondern jeder entstehende Dienst ein Produkt darstellt. Das zuständige Team muss das Produkt während seines gesamten Lebenszyklus betreuen, von dem Zeitpunkt seiner Entwicklung über den Betrieb bis hin zur Abschaltung des Services. Dieses Vorgehen hat zwei interessante Aspekte. Erstens muss, wie oben beschrieben, das Team in der Lage sein alle entwicklungsrelevanten Entscheidungen eigenständig und im Hinblick auf die Qualität ihres Produktes zu treffen. Ohne diese Eigenverantwortung für den Service kann sich keine Identifikation mit dem entstandenen Produkt entwickeln und Konflikte sind vorprogrammiert. Zweitens ist ein Team durch den Microservice-Ansatz aber auch für eben jene Qualität zuständig und entsprechend für Serviceausfälle haftbar. Dieser Sachverhalt führt langfristig zu einer höheren Qualität hinsichtlich Funktionalität und Wartbarkeit der Services. Dieses Vorgehen folgt dem Prinzip „Eat your own dog food“. Wenn man selbst für den Betrieb des Produktes und dessen Qualität zuständig ist, wird man Entscheidungen so treffen, dass man wenig Wartungsaufwand hat und bei Fehlern eine einfache und effektive Fehleridentifikation möglich ist. Das beschriebene Prinzip ist allgemein auch als DevOps bekannt [3].

Microservices und agile Softwareentwicklung

Der Microservice-Ansatz wird häufig auch als ein agiler Architekturstil bezeichnet, der ähnliche Auswirkungen auf moderne Softwarearchitekturen hat wie die agile Softwareentwicklung auf die Methodologie der Softwareentwicklung. Betrachtet man die bisher beschriebenen Prinzipien kann man viele Parallelen feststellen. In beiden Konzepten geht es um die Entwicklung von Produkten und nicht die Durchführung von Projekten. Im Fokus der Entwicklung steht an erster Stelle die geforderte Fachlichkeit korrekt und zur Zufriedenheit der Kunden umzusetzen. Um dies zu gewährleisten, ist ein weiteres zentrales Prinzip die Bildung von eigenverantwortlichen Teams mit tiefgreifenden Entscheidungsgewalten. Dadurch wird auch die Identifikation mit dem entstehenden Produkt verstärkt. Generell kann man sagen, dass beide Konzepte in vielen Bereichen gleichen Prinzipen folgen und diese lediglich von anderen Blickwinkeln aus betrachten.

Ein Thema das bei der agilen Softwareentwicklung jedoch schon immer für Diskussionen gesorgt hat ist dessen Skalierbarkeit. Bei der Entwicklung großer Softwaresysteme, besonders mit monolithischer Architektur, ist die Adaption häufig schwierig oder scheitert. Als Folge gibt es mittlerweile mehrere Methoden (SAFe [4], Nexus [5]) die zur Skalierung von agilen Softwareentwicklung entwickelt wurden. Ein zentraler Punkt in all diesen Modellen ist immer wie agile Entwicklungsteams unabhängig voneinander entwickeln können und wie eine Abstimmung unter den Teams durchgeführt werden kann. Genau in diesem Aspekt kann der Microservice-Ansatz ein großer Schritt vorwärts sein. Wie bereits erwähnt propagiert er ähnliche organisatorische Konzepte wie die agile Softwareentwicklung. Zusätzlich beschreibt er jedoch technische Rahmenbedingungen, um die  einzelnen Dienste so unabhängig wie möglich zu entwickeln (shared nothing). Somit kann, wenn der Architekturstil korrekt angewendet wird, ein agiles Team 1 bis n Dienste isoliert entwickeln. Die Abstimmung zwischen mehreren Teams beschränkt sich dabei lediglich auf die Schnittstellen. Jedes Team ist für die Funktion seiner Dienste zuständig und muss deren Betrieb garantieren.

Zusammenfassung

Wie im Artikel beschrieben sind Microservices ein Ansatz zur Entwicklung größerer Softwaresystemen bestehend aus einzelnen kleinen Diensten. Jeder Dienst beschäftigt sich dabei mit klar abgegrenzten Geschäftsbereichen und kann so effektiv von einzelnen Teams erstellt werden. Den Microservice-Ansatz lediglich als Architekturstil zu betrachten ist jedoch falsch. Viele Aspekte sind organisatorischer Natur und beschreiben, wie Projekte skalierbar durchgeführt werden können. Ein zentraler Punkt ist dabei die Zusammenstellung von funktionsübergreifenden Teams mit einem hohen Maß an Eigenverantwortlichkeit. Durch diese Maßnahme soll die Identifikation der Teams mit den entstehenden Produkten gestärkt und somit langfristig eine höhere Qualität der Systeme erreicht werden.

Dieser Vortrag wurde im Rahmen der DOAG Konferenz 2016 gehalten.

Referenzen

[1] J. Lewis und M. Fowler: Microservices – http://martinfowler.com/articles/microservices.html
[2] M. E. Conway: How Do Committees Invent?; Bd. Datamation magazine, 1968
[3] M. Loukides: What is DevOps? – http://radar.oreilly.com/2012/06/what-is-devops.html
[4] Scale Agile Framework (SAFe) – http://scaledagileframework.com/
[5] Nexus Framework – https://www.scrum.org/Resources/The-Nexus-Guide