Kapitel 1. Auf dem Weg zu einer Microservices-Architektur
Diese Arbeit wurde mithilfe von KI übersetzt. Wir freuen uns über dein Feedback und deine Kommentare: translation-feedback@oreilly.com
Das Ziel dieses Buches ist es, dir beim Aufbau einer funktionierenden Microservices-Architektur zu helfen. Auf den folgenden Seiten findest du Ratschläge für den Aufbau von Software, die sowohl Meinungen als auch Vorschriften enthalten. Diese Ratschläge stammen aus den Erfahrungen, die wir in der Praxis gesammelt haben, sowohl aus erfolgreichen Implementierungen als auch aus solchen, die besser hätten laufen können. Wir haben diese Lektionen zu einem Modell verfeinert, mit dem du hoffentlich dein eigenes System schneller zum Laufen bringst.
In letzter Zeit hat der Microservices-Stil für die Entwicklung von Software stark an Popularität gewonnen. In den frühen 2010er Jahren entstand der Begriff Microservices, um eine neue Art der Softwarearchitektur zu beschreiben. Anwendungen, die in diesem neuen Stil erstellt werden, bestehen aus kleinen, unabhängigen Komponenten, die zusammenarbeiten. Seitdem ist die Verbreitung von Microservices sprunghaft angestiegen. Start-ups, Großunternehmen und alle dazwischen haben Microservices-Architekturen gelernt und implementiert. Das wachsende Ökosystem von Tools, Diensten und Lösungen in diesem Bereich zeugt von seiner großen Beliebtheit. Allied Market Research prognostiziert, dass der weltweite Markt für Microservices-Architekturen von derzeit 2,07 Mrd. USD auf 8,07 Mrd. USD im Jahr 2026 anwachsen wird. Diese Zahlen deuten darauf hin, dass das Interesse groß ist, die Akzeptanz groß und die Arbeit an Microservices groß ist.
Für viele hat sich die Entwicklung von Software nach dem Microservices-Prinzip als Herausforderung erwiesen. Die Wahrheit ist, dass die Implementierung eines Microservices-Systems nicht einfach ist. Das Zusammenspiel vieler unabhängiger Teile ist schwieriger, als es vielleicht klingt. Die Kosten für Verwaltung, Wartung, Support und Tests summieren sich im System. Im großen Maßstab können diese Kosten unerschwinglich werden. Wenn du nicht aufpasst, kann der Aufwand für die Verwaltung des Systems dazu führen, dass Microservices wie eine schlechte Idee erscheinen.
Aber die Vorteile der Entwicklung von Microservices machen die Risiken wett. Gut gemachte Microservices ermöglichen schnellere und sicherere Softwareänderungen im großen Maßstab. Schnellere und sicherere Änderungen bedeuten mehr Agilität für dein Unternehmen. Diese Agilität führt zu besseren Ergebnissen für dein Unternehmen und deine Organisation.
Der Trick, um all diesen Wert freizusetzen, ist die richtige Architektur zur Unterstützung der Dienste zu haben. Sie muss die Systemkosten senken, ohne den Wert der unabhängigen Dienste zu schmälern. Um diese Architektur aufzubauen, musst du frühzeitig wichtige Entscheidungen treffen. Diese Entscheidungen werden sich auf Methoden, Prozesse, Teams, Technologien und Werkzeuge erstrecken. Sie müssen auch zusammenarbeiten, um ein optimiertes Ganzes zu bilden.
Ein guter Weg, ein solches System aufzubauen, ist die Evolution. Du kannst mit ein paar kleinen Entscheidungen beginnen und nach und nach lernen und wachsen. Die meisten Early Adopters sind durch iteratives Experimentieren zu Microservices gekommen. Sie sind nicht mit dem Ziel gestartet, eine Microservices-basierte Anwendung zu entwickeln. Stattdessen sind sie durch einen kontinuierlichen Prozess der Optimierung und Verbesserung dazu gekommen.
Von Grund auf neu zu beginnen und zu iterieren braucht Zeit. Aber die gute Nachricht ist, dass du die Erfahrungen dieser Praktiker nutzen kannst, um dein System schneller aufzubauen. Beginne deinen Aufbau mit einem Fundament aus Mustern, Methoden und Werkzeugen, die gemeinsam erfolgreich eingesetzt wurden. Dann optimierst du das System, um die einzigartigen Ziele und Einschränkungen deines Unternehmens zu erfüllen.
In diesem Buch haben wir die Entscheidungen dokumentiert, die eine solide Grundlage für Microservices bilden. Bevor wir in die Details des Modells eintauchen, wollen wir eine wichtige Frage klären. Was genau verstehen wir unter "Microservices"?
Was sind Microservices?
Es gibt nicht die eine offizielle, kanonische Definition für Microservices. Ein guter Ausgangspunkt ist der bahnbrechende Artikel von James Lewis und Martin Fowler über Microservices aus dem Jahr 2014. In diesem Artikel beschreiben sie Microservices als:
ein Ansatz zur Entwicklung einer einzelnen Anwendung als eine Reihe kleiner Dienste, die jeweils in einem eigenen Prozess laufen und mit leichtgewichtigen Mechanismen kommunizieren. [...], die um die Geschäftsfähigkeiten herum aufgebaut sind und unabhängig voneinander von vollautomatischen Bereitstellungsmaschinen eingesetzt werden können.
Das eigentliche Herzstück des Artikels von Lewis und Fowler ist die Reihe von neun Eigenschaften, die Microservices besitzen. Ihre Liste beginnt mit dem Kernmerkmal von Microservices , der Komponentisierung durch Services, d.h. der Aufteilung einer Anwendung in kleinere Services. Von dort aus geht es weiter zu einer großen Bandbreite an Fähigkeiten. Sie dokumentieren die Notwendigkeit eines Organisations- und Managementdesigns mit den Merkmalen der Organisation rund um die Geschäftsfähigkeit und der dezentralen Steuerung. Sie weisen auf DevOps und agile Lieferpraktiken hin, wenn sie die Automatisierung der Infrastruktur und Produkte statt Projekte vorstellen. Sie nennen auch einige wichtige Architekturprinzipien, wie wie Smart Endpoints und Dumb Pipes, Design for Failure und evolutionäres Design.
Jedes dieser Merkmale ist es wert, verstanden zu werden, und wir empfehlen dir, den Artikel zu lesen, falls du das noch nicht getan hast. Zusammen bilden diese Merkmale eine ganzheitliche Lösung mit einer großen Anzahl von Anliegen. Dazu gehören Technologie, Infrastruktur, Technik, Operationalisierung, Governance, Teamstruktur und Kultur.
Als Kontrast dazu hier eine andere Definition für Microservices aus dem Buch Microservice Architecture von Irakli Nadareishvili, Ronnie Mitra, Matt McLarty und Mike Amundsen (O'Reilly):
Ein Microservice ist eine unabhängig einsetzbare Komponente mit begrenztem Umfang, die Interoperabilität durch nachrichtenbasierte Kommunikation unterstützt. Die Microservice-Architektur ist ein Stil für die Entwicklung hoch automatisierter, entwicklungsfähiger Softwaresysteme, die aus fähigkeitsorientierten Microservices bestehen.
Diese Definition ( ) ähnelt der von Lewis und Fowler, legt aber besonderes Augenmerk auf begrenzte Geltungsbereiche, Interoperabilität und nachrichtenbasierte Kommunikation. Außerdem wird zwischen Microservices und der Architektur, die sie ermöglicht, unterschieden.
Dies sind nur zwei Beispiele aus einer Vielzahl von Microservices-Definitionen. Wie bei diesen Beispielen sind die meisten Definitionen im Großen und Ganzen ähnlich, unterscheiden sich aber leicht in ihrem Fokus. Sie sind aber meist so unterschiedlich, dass es schwer zu beurteilen ist, ob du ein Microservices-System aus dem Lehrbuch gebaut hast.
In der Welt der Technologie sind Namen wichtig, weil sie uns eine einfache Möglichkeit geben, komplexe Konzepte zu kommunizieren. In diesem Fall erlaubt uns die Bezeichnung "Microservices", eine Art von Software Architektur zu beschreiben, die drei allgemeine Design-Merkmale aufweist:
-
Die Anwendungsarchitektur besteht in erster Linie aus maschinell abrufbaren "Diensten", die in einem Netzwerk zur Verfügung gestellt werden.
-
Die Größe (oder Grenzen) von Diensten ist ein wichtiger Gestaltungsfaktor. Zu diesen Grenzen gehören Faktoren wie Laufzeit, Entwurfszeit und Menschen.
-
Das Softwaresystem, die Organisation und die Arbeitsweise werden ganzheitlich optimiert, um ein Ziel zu erreichen.
Dies ist eine ziemlich allgemeine Reihe von Gestaltungsmerkmalen. Es werden zum Beispiel keine Organisationsstile, spezielle Werkzeuge oder Architekturprinzipien beschrieben, die verwendet werden sollten. Es werden auch keine formalen Muster oder Praktiken definiert. Stattdessen werden uns gerade genug Merkmale an die Hand gegeben, um ein Microservices-System zu erkennen, wenn wir es sehen.
Die Wahrheit ist, dass du fast jedes API-basierte System als Microservices-Architektur bezeichnen kannst, wenn du dich nur genug anstrengst. Aber der eigentliche Fokus sollte auf dem Ziel deines Systems liegen. Wir denken, dass die Frage, warum du Microservices bauen solltest, viel aufschlussreicher ist als die Frage, was sie sind. Es gibt zwar viele potenzielle Vorteile von Microservices, aber wir glauben, dass der beste Grund, Software auf diese Weise zu entwickeln, darin besteht, die Koordinationskosten zu senken .
Senkung der Koordinationskosten
Unternehmen auf der ganzen Welt haben mit der Einführung von Microservices-Architekturen Erfolg gehabt. Die Praktiker, mit denen wir gesprochen haben, berichten fast ausnahmslos von einer schnelleren Softwarebereitstellung. Wir glauben, dass diese Verbesserung auf den grundlegenden Vorteil des Microservices-Stils zurückzuführen ist: eine Verringerung der Koordinationskosten.
Es gibt viele Möglichkeiten, die Geschwindigkeit der Softwareentwicklung zu erhöhen. Der Aufbau von Software auf Basis von Microservices ist nur eine Möglichkeit. Du könntest zum Beispiel ein System schnell erstellen, indem du an allen Ecken und Enden sparst und "technische Schulden" machst, mit denen du dich später auseinandersetzen musst. Oder du kannst dich weniger auf Stabilität und Sicherheit konzentrieren und dein Produkt einfach auf den Markt bringen. In manchen Situationen und für manche Unternehmen sind das vernünftige Ansätze.
Aber Systeme, die u.a. für den Finanz-, Gesundheits- und Regierungssektor entwickelt werden, dürfen keine Kompromisse bei der Sicherheit eingehen, um die Geschwindigkeit zu erhöhen. Dennoch verlangen die Wettbewerbs- und Marktkräfte in diesen Branchen wie in jeder anderen auch eine höhere Geschwindigkeit. Hier kann ein Microservices-System glänzen. Es bietet einen architektonischen Ansatz, mit dem du die Geschwindigkeit erhöhen kannst, ohne die Sicherheit zu beeinträchtigen. Und das in großem Maßstab.
Das Problem der Koordinationskosten
Die Entwicklung komplexer Software ist harte Arbeit. In Filmen und im Fernsehen kann ein genialer Programmierer heldenhaft an einem schlaflosen Wochenende ein weltveränderndes Produkt entwickeln. Im wirklichen Leben braucht es viele Leute und eine Menge Zeit, um ein hochwertiges Ergebnis zu erzielen. Mehrere Teams, die an einem komplexen Projekt arbeiten, implementieren in der Regel verschiedene Teile des Systems, die unabhängigen Plänen folgen und in unterschiedlichem Tempo arbeiten. Von Zeit zu Zeit müssen diese Teile integriert werden, um die Abhängigkeiten aufzulösen. Zu diesem Zeitpunkt müssen die meist autonomen Teams ihre Arbeit koordinieren (siehe Abbildung 1-1).
Stell dir vor, Jane ist die Teamleiterin, die für den Workstream Buchhaltung zuständig ist. Ihr Team hat gerade einen Sprint abgeschlossen und ist von einer Komponente abhängig, die von dem Team entwickelt wird, das für das Modul "Versand" zuständig ist und von Tyrone geleitet wird. Da Roadmaps unabhängig sind, könnte es sein, dass Tyrones Team mit der Implementierung der benötigten Komponente im Workstream Versand noch nicht fertig ist. An diesem Punkt hat Jane zwei Möglichkeiten: Sie kann entweder warten, bis die Komponente geliefert wird (wobei sie der Sicherheit den Vorrang gibt, aber die Geschwindigkeit opfert, indem sie ihr Team auf Eis legt), und einen ordentlichen Integrationstest durchführen, oder sie kann sich auf einen vereinbarten Schnittstellenvertrag zwischen ihrem Team und dem von Tyrone verlassen und davon ausgehen, dass sein Team die Komponente genau wie geplant liefern wird. Im letzteren Fall würde Jane ohne Unterbrechung weitermachen, was die Geschwindigkeit ihres Teams erhöht, aber möglicherweise die Gesamtsicherheit des Systems gefährdet, da die Integrationstests nicht zum frühestmöglichen Zeitpunkt durchgeführt wurden und man von einem "glücklichen Weg" ausgegangen ist.
Jeder Teamleiter in einer komplexen Multiteam-Umgebung steht regelmäßig vor der Entscheidung, ob er die Kosten für die Koordination ignorieren und den Schwung beibehalten oder ob er die Notwendigkeit der Koordination anerkennen und langsamer werden soll. Normalerweise entscheiden wir uns für das eine oder das andere, indem wir das Risiko und den Nutzen abwägen. Aber wenn diese Entscheidungen in einem ausreichend komplexen System häufig genug getroffen werden, besteht ein ausgeprägtes Spannungsverhältnis zwischen Geschwindigkeit und Sicherheit.
Die Spannung ist real, aber sie hat nichts mit unseren Urinstinkten zu tun und es gibt einen Weg, sie zu lösen. Was wäre, wenn wir ein System hätten, das so konzipiert ist, dass die Koordinationskosten minimiert werden? Was wäre, wenn die Teams sich nicht für den einen oder anderen Weg entscheiden müssten, sondern die meiste Zeit gar nicht vor der Wahl stünden? Ein solches Design, bei dem die Minimierung des Koordinationsaufwands im Vordergrund steht, ist möglich, wenn autonome Teams an kleinen, isolierten Aufgaben arbeiten. Und genau das ist es, worum es bei der Microservices-Architektur im Wesentlichen geht.
Die Erkenntnis, dass die grundlegende Kraft beim Aufbau erfolgreicher Microservices-Architekturen in der Minimierung der Koordination liegt, ist äußerst nützlich. Es gibt uns einen universellen Lackmustest. Der Aufbau komplexer verteilter Systeme wie einer Microservices-Architektur ist nicht einfach, und im Zweifelsfall sollten wir uns immer fragen: "Wird diese Entscheidung, vor der ich stehe, die Koordinationskosten für meine Teams reduzieren oder nicht?" Die richtige Antwort wird viel deutlicher, wenn wir Entscheidungen aus der Perspektive der Koordinationskosten betrachten.
Letztendlich sind Microservices beliebt geworden, weil sie Unternehmen zum Erfolg verhelfen. Moderne Unternehmen stehen unter einem unglaublichen Druck, sich immer öfter und schneller anzupassen, zu verändern und zu verbessern. Die Investition in eine Technologiearchitektur, die gezielt auf die Veränderungsgeschwindigkeit und -sicherheit einer großen Organisation ausgelegt ist, ist sehr sinnvoll. Der Microservices-Stil ermöglicht es Unternehmen, die in komplexen Bereichen tätig sind, die Agilität eines einfacheren, kleineren Unternehmens zu haben, während sie weiterhin die Leistung und Reichweite ihrer tatsächlichen Größe nutzen können. Das ist unglaublich attraktiv und die wachsende Akzeptanz beweist das - allerdings gibt es die Vorteile nicht umsonst. Es erfordert eine Menge Vorarbeit, Konzentration und Entscheidungsfindung, um eine Microservices Architektur aufzubauen, die diesen Wert freisetzen kann.
Die schwierigen Teile
Eine der größten Hürden für Microservices-Einsteiger ist der Umgang mit dem enormen Umfang und der Breite eines Microservices-Systems. Vielleicht konzentrierst du dich zunächst darauf, kleinere, begrenzte Dienste zu erstellen. Aber schon bald wirst du feststellen, dass du die richtige Infrastruktur, Datenmodelle, Frameworks, Teammodelle und Prozesse entwickeln musst, um sie zu unterstützen. Das ist eine Menge Arbeit, und die Bewältigung dieses Umfangs kann zu einigen einzigartigen Herausforderungen führen. Hier sind die drei großen Probleme, mit denen Architekten und Ingenieure bei der Entwicklung von Microservices konfrontiert werden:
- Lange Rückkopplungsschleifen
-
Eine große Herausforderung ist, dass die Auswirkungen von Entscheidungen in einem Microservices-System nicht leicht zu messen sind. Aus den Entscheidungen, die du heute triffst, können Probleme entstehen, die sich aber erst viel später bemerkbar machen. Wenn du zum Beispiel anfängst, entscheidest du dich vielleicht für eine gemeinsame Kommunikationsbibliothek, damit deine Dienste leichter miteinander kommunizieren können. Im Laufe der Zeit kann sich herausstellen, dass es ein großes Problem ist, diese Bibliothek für alle deine Microservices und Teams auf dem neuesten Stand zu halten. Der springende Punkt ist, dass du die Auswirkungen deiner Entscheidung erst dann verstehst, wenn Probleme auftauchen, was es schwierig macht, Optionen zu bewerten und zwischen ihnen zu wählen.
- Zu viele bewegliche Teile
-
Im Kern ist ein Microservices-System ein komplexes, adaptives System. Das bedeutet, dass sich jeder Teil des Systems in irgendeiner Weise auf die anderen Teile auswirkt. Wenn all diese Teile zusammenkommen, entsteht ein neuartiges Systemverhalten. Wenn du schon einmal ein neues Werkzeug oder einen neuen Prozess in einem Unternehmen eingeführt hast, hast du das wahrscheinlich selbst erlebt. Manche Teams nehmen die neuen Reize sofort an und verändern sich, andere brauchen Hilfe und Unterstützung, um sich anzupassen, aber egal wie, am Ende hat das fast immer Auswirkungen auf die Arbeitsweise und die Entscheidungen, die getroffen werden. Zum Beispiel müssen Technologieteams, die Docker-Container einführen, zwangsläufig ihren Entwicklungs- und Release-Lebenszyklus anpassen, weil sie das Container-Bereitstellungsmodell übernehmen. Manchmal sind diese Folgen geplant, aber oft müssen wir uns mit den unbeabsichtigten Folgen der eingeführten Änderungen auseinandersetzen. Diese Komplexität macht das Design von Microservices-Systemen schwierig. Es ist schwierig, die spezifischen Auswirkungen der eingeführten Änderungen vorherzusagen, so dass die Gefahr besteht, dass wir mit einem neuen Architekturmodell mehr Schaden als Nutzen anrichten.
- Analyse-Lähmung
-
Wenn wir das Problem der langen Rückkopplungsschleifen für unsere Entscheidungen mit dem komplexen System, das wir entwerfen müssen, verbinden, ist es leicht zu erkennen, warum die Microservices-Architektur eine Herausforderung ist. Die Entscheidungen, die du treffen musst, haben große Auswirkungen und sind gleichzeitig schwer zu messen. Das kann zu endlosen Spekulationen, Diskussionen und Bewertungen von Architekturentscheidungen führen, weil man Angst hat, das falsche System zu bauen. Anstatt ein System zu bauen, mit dem die Geschäftsergebnisse erreicht werden können, geraten wir in einen Zustand der Unentschlossenheit und versuchen, die endlosen Permutationen unserer Entscheidungen zu modellieren. Dieser Zustand wird gemeinhin als Analyseparalyse bezeichnet. Da hilft es auch nicht, dass das Internet voll von Horrorgeschichten, Ratschlägen und widersprüchlichen bewährten Methoden für den Aufbau einer Microservices-Architektur ist.
Die eigentliche Herausforderung beim Aufbau einer Microservices-Architektur ist der Umgang mit einem großen, komplizierten System, das sich über einen riesigen Bereich erstreckt. Die gute Nachricht ist, dass es sich dabei nicht um ein einzigartiges Problem handelt, das es zu lösen gilt. In diesem Buch werden wir eine Reihe von Praktiken und Mustern zusammentragen und anwenden, die sich für diese Art von Domäne entwickelt haben. Außerdem werden wir Werkzeuge vorstellen und implementieren, die diese Arbeitsweisen verkörpern und die Arbeit in einem Microservices-System einfacher, sicherer, billiger und schneller machen.
Learning by Doing
Bisher haben wir festgestellt, dass der Microservices-Stil dir dabei helfen kann, Software schneller zu entwickeln, ohne Kompromisse bei der Sicherheit einzugehen. Wir haben aber auch festgestellt, dass der Weg zu einer guten Microservices-Architektur schwierig und voller schwieriger und komplexer Entscheidungen ist. Viele der erfolgreichen Microservices-Implementierer, mit denen wir gesprochen haben, haben ihre Systeme durch ständige Iterationen und Verbesserungen aufgebaut. Oftmals mussten sie Architekturen aufbauen, die fehlschlugen, bevor sie verstanden, wie man ein funktionierendes System aufbaut.
Wenn du unbegrenzt Zeit hättest, könntest du eine großartige Microservices-Architektur allein durch Experimentieren aufbauen. Du könntest endlose Organisationsmodelle übernehmen, jede Methode ausprobieren und Microservices in verschiedenen Größen bauen. Solange du deine Ergebnisse messen könntest, würdest du das System immer weiter verbessern. Wenn du genügend Versuche unternimmst, wirst du am Ende ein System haben, das für dich funktioniert, und eine Menge Erfahrung im Aufbau von Microservice-Systemen.
Wahrscheinlich hast du aber nicht den Luxus, unbegrenzt Zeit zu haben. Wie baust du also das Know-how auf, das du brauchst, um bessere Microservices zu entwickeln?
Um diese Herausforderung zu meistern, haben wir ein präskriptives Microservices-Modell entwickelt. Wir haben Entscheidungen über Teamdesign, Prozesse, Architektur, Infrastruktur und sogar Tools und Technologien getroffen. Wir werden eine Vielzahl von Themenbereichen abdecken und gleichzeitig eine Lösung entwickeln, die diese Bereiche zusammenführt. Unsere Entscheidungen beruhen auf Meinungen, die auf Erfahrungen mit dem Aufbau von Microservices-Systemen für große Unternehmen basieren. Wenn du unseren Anweisungen folgst, wirst du am Ende des Buches ein einfaches, betriebsbereites Microservices-System in einer Cloud-basierten Architektur aufgebaut haben.
Hinweis
Um unsere Beispiele für Microservices lebendig werden zu lassen, werden wir ein fiktives Reservierungssystem einer Fluggesellschaft als Hintergrund verwenden. Es handelt sich dabei um eine stark vereinfachte Version eines echten Reservierungssystems. Unser einfaches Flugreservierungssystem umfasst zwei Funktionen: einen reinen Fluginformationsdienst und einen Sitzplatzreservierungsdienst.
Unser Ziel ist es, dich dabei zu unterstützen, so schnell wie möglich deine erste Microservices-Implementierung zu erstellen. Unserer Erfahrung nach ist der Aufbau eines echten Systems der beste Weg, um ein echtes Verständnis für die Arbeit und die wichtigsten Entscheidungen zu bekommen. Wir erwarten nicht, dass du mit allen unseren Entscheidungen einverstanden bist. Vielmehr ist das Hinterfragen der Entscheidungen, die wir für dich getroffen haben, ein wichtiger Teil der Lernreise! Wir hoffen, dass das Modell, das wir gemeinsam bauen, nur das erste von vielen Microservices-Systemen ist, die du bauen wirst.
Das Dreyfus-Modell des Kompetenzerwerbs
Das Befolgen von Anweisungen zu Beginn einer Lernreise ist ein bewährter Weg zum Erwerb von Fachwissen. In Stuart und Hubert Dreyfus' Fünf-Stufen-Modell des Kompetenzerwerbs bei Erwachsenen wird in der ersten Stufe die Befolgung von Anweisungen vorausgesetzt, bevor Kompetenz und Fachwissen erworben werden.
Das Microservices-Modell "Up and Running"
Der Umfang einer Microservices-Architektur ist ziemlich groß. Leider können wir in diesem Buch nicht den gesamten Umfang abdecken. Wir haben uns jedoch bemüht, die Themenbereiche zu behandeln, die für ein Microservices-System am wichtigsten sind und den größten Einfluss auf den Erfolg haben. Werfen wir einen kurzen Blick darauf, was wir in unserem "laufenden" Microservices-Modell behandeln werden.
- Team Design
-
Zu Beginn unseres Builds in Kapitel 2 werden wir uns mit der menschlichen Seite eines Microservice-Systems befassen. Wir werden die Herausforderungen eines effektiven Teamdesigns und die grundlegenden Faktoren, die die Koordination von Microservices beeinflussen, aufdecken. Außerdem stellen wir die Teams vor, die wir in unserem Beispielsystem verwenden werden, sowie ein Tool namens Team Topologies, das uns bei der Gestaltung der Teams hilft.
- Microservice Design
-
Nachdem wir die Teams zusammengestellt haben, werden wir in Kapitel 3 den SEED(S)-Prozess vorstellen. Dabei handelt es sich um einen Entwurfsprozess, der uns dabei hilft, Microservices zu entwickeln, die die Bedürfnisse der Nutzer und Konsumenten mit brauchbaren Schnittstellen und Verhaltensweisen erfüllen. In Kapitel 4 widmen wir uns dann dem Problem, die richtigen Grenzen für unsere Beispiel-Microservices zu entwerfen. Außerdem stellen wir einige wichtige Konzepte des Domain-Driven Design vor und nutzen ein Verfahren namens Event Storming, um unsere Dienste "richtig zu dimensionieren".
- Datengestaltung
-
Daten sind einer der schwierigsten Aspekte des Designs von Microservices. In Kapitel 5 werfen wir einen Blick auf die Datenfaktoren, die du in einem Microservices-System berücksichtigen musst. Wir stellen das Konzept der Datenunabhängigkeit vor und legen den Grundstein für die Datenarchitektur in unserem Beispielprojekt.
- Cloud-Plattform
-
Unsere Microservices-Implementierung wird auf einer Cloud-basierten Infrastruktur aufgebaut. In Kapitel 6 werden wir die Prinzipien der unveränderlichen Infrastruktur und Infrastructure as Code (IaC) als Grundlage für unsere Microservices-Infrastruktur einführen und umsetzen. Außerdem stellen wir AWS als unsere Cloud-Plattform vor und bauen eine CI/CD-Pipeline auf Basis von GitHub Actions auf. In Kapitel 7 werden wir diese Pipeline nutzen, um eine AWS-basierte Microservices-Infrastruktur zu entwerfen und zu entwickeln, die Netzwerke, einen Kubernetes-Cluster und ein GitOps-Bereitstellungstool umfasst.
- Microservices Entwicklung
-
Nachdem wir unsere Infrastrukturplattform aufgebaut haben, können wir uns an die Entwicklung der Microservices machen. Zunächst behandeln wir in Kapitel 8 die Prinzipien und Werkzeuge, die du für den Erfolg brauchst. In Kapitel 9 werden wir dann zwei unabhängige, heterogene Microservices für unsere Beispielanwendung implementieren.
- Loslassen und verändern
-
Wir werden die gesamte Lösung in Kapitel 10 zusammenführen, wo wir einen der von uns entwickelten Beispiel-Microservices auf der von uns entwickelten cloudbasierten Plattform bereitstellen werden. Dazu nutzen wir eine Reihe von Technologien wie DockerHub, Kubernetes, Helm und Argo CD. Nach der Veröffentlichung werden wir in Kapitel 11 einen Rückblick auf das System werfen.
Hinweis
Das Modell, das wir entwickelt haben, basiert auf fünf Grundprinzipien, darunter das Zwölf-Faktoren-Muster für Apps. Wenn du daran interessiert bist, kannst du die Leitprinzipien unseres Modells im GitHub-Repository dieses Buches nachlesen.
Wir hoffen, dass dieser kurze Überblick dir einen Eindruck vom Umfang unseres Modells und der Beispielanwendung vermittelt. Am Ende des Buches werden wir ein vollwertiges System implementiert haben. Um das zu erreichen, müssen wir viele Entscheidungen treffen. Das erste Werkzeug, das wir dafür brauchen, ist eine Möglichkeit, die wirklich wichtigen Entscheidungen im Auge zu behalten.
Entscheidungen, Entscheidungen, Entscheidungen...
Wenn es um die Entwicklung von Software geht, sind Entscheidungen eine große Sache. Professionelle Softwareentwickler und -architekten werden für die Entscheidungen, die sie treffen, und die Probleme, die sie lösen, gut bezahlt. Die Qualität der Software und die Geschäftsergebnisse, die sie erzielen, hängen von der Qualität dieser Entscheidungen ab.
Aber Entscheidungen sind nicht immer leicht zu treffen. Sie sind auch nicht immer richtig. Wir treffen die besten Entscheidungen, die wir angesichts der Informationen, Erfahrungen und Talente, die wir haben, treffen können. Wenn sich eine dieser Variablen ändert, sollten sich auch unsere Entscheidungen ändern. Manche Entscheidungen sind zu diesem Zeitpunkt richtig, werden aber überholt, wenn sich die Technologie, die Menschen oder die Situation ändern. Manche Entscheidungen waren von vornherein nie gut. In jedem Fall brauchen wir eine Möglichkeit, die wichtigen Entscheidungen festzuhalten, damit wir sie im Laufe der Zeit neu bewerten und verbessern können.
Um dieses Bedürfnis zu befriedigen, werden wir ein Werkzeug namens " Architecture Decision Record" (oder ADR) verwenden. Wir sind uns nicht sicher, wer den Begriff ADR erfunden hat oder wann er zum ersten Mal verwendet wurde, aber die Idee, Entwurfsentscheidungen zu dokumentieren, gibt es schon seit langem. Das eigentliche Problem ist, dass sich die meisten Leute nicht die Zeit nehmen, dies zu tun. Unserer Erfahrung nach sind ADRs ein äußerst nützliches Instrument und eine gute Möglichkeit, sich Klarheit über die Entscheidungen zu verschaffen, die getroffen werden müssen.
Ein gutes Entscheidungsprotokoll muss vier wichtige Elemente enthalten:
- Kontext
-
Was ist die Herausforderung? Was ist das Problem, das wir zu lösen versuchen? Wie lauten die Einschränkungen? Ein Entscheidungsprotokoll sollte uns eine Zusammenfassung dieser Kontextelemente liefern. Auf diese Weise können wir die Gründe für eine Entscheidung nachvollziehen und verstehen, warum sie eventuell aktualisiert werden muss.
- Alternativen
-
Eine Entscheidung ist nur dann eine Entscheidung , wenn es eine Wahl gibt, die getroffen werden muss. Ein gutes Entscheidungsprotokoll sollte uns helfen zu verstehen, welche Wahlmöglichkeiten es gibt. Das hilft uns, den Kontext und den "Auswahlraum" zum Zeitpunkt der Entscheidung besser zu verstehen.
- Auswahl
-
Im Mittelpunkt einer Entscheidung steht die Wahl. In jedem Entscheidungsprotokoll muss die getroffene Wahl dokumentiert werden.
- Aufschlag
-
Entscheidungen haben Konsequenzen und ein Entscheidungsprotokoll sollte die wichtigsten davon dokumentieren. Was sind die Kompromisse? Wie wirkt sich unsere Entscheidung auf die Art und Weise aus, wie wir arbeiten, oder auf andere Entscheidungen, die getroffen werden müssen?
Du kannst Entscheidungsprotokolle erstellen, wie du willst. Du kannst sie als Textdateien verfassen, ein Projektmanagement-Tool verwenden oder sie sogar in einer Tabellenkalkulation erfassen. Das Format und die Werkzeuge sind weniger wichtig als der Inhalt. Solange du die Bereiche, die wir beschrieben haben, erfasst, hast du ein gutes Entscheidungsprotokoll.
Für unser Beispielprojekt verwenden wir ein bestehendes Format namens Lightweight Architectural Decision Record (LADR). Das LADR-Format wurde von Michael Nygard entwickelt und ist eine schöne, übersichtliche Art, einen Entscheidungssatz zu dokumentieren. Lasst uns LADR kennenlernen, indem wir gemeinsam ein erstellen.
Tipp
Wenn du etwas anderes als LADR verwenden möchtest, findest du bei Joel Parker Henderson eine tolle Liste mit ADR-Formaten und Templates.
Ein leichtgewichtiges architektonisches Entscheidungsprotokoll schreiben
Die erste wichtige Entscheidung, die wir auf festhalten werden, ist die Entscheidung, unsere Entscheidungen zu dokumentieren. Einfacher ausgedrückt: Wir erstellen ein ADR, das besagt, dass wir unsere Entscheidungen aufzeichnen wollen. Wie wir bereits erwähnt haben, verwenden wir das LADR-Format. Das Schöne an LADR ist, dass es sehr einfach zu handhaben ist. So können wir unsere Entscheidungen in einfachen Textdateien festhalten, die wir schnell schreiben können. Da wir es mit Textdateien zu tun haben, können wir unsere Entscheidungsdatensätze sogar auf dieselbe Weise verwalten wie unseren Quellcode.
LADRs werden in einem Textformat namens Markdown geschrieben, das eine elegante und einfache Möglichkeit bietet, Dokumentation zu schreiben. Das Tolle an Markdown ist, dass es für Menschen in seiner Rohform leicht zu lesen ist und die meisten gängigen Tools wissen, wie man es wiedergibt. Confluence, GitLab, GitHub und SharePoint zum Beispiel können Markdown verarbeiten und als formatiertes, für Menschen lesbaresDokument darstellen.
Um unsere erste Markdown-basierte LADR zu erstellen, öffnest du deinen bevorzugten Texteditor und beginnst mit der Arbeit an einem neuen Dokument. Als Erstes legen wir die Struktur fest.
Füge den folgenden Text zu deiner LADR-Datei hinzu:
#
OPM1: Use ADRS for decision tracking##
Status Accepted##
Context##
Decision##
Consequences
Dies sind die wichtigsten Elemente unseres Entscheidungsdatensatzes. Die #
Zeichen vor den Zeilen sind Markdown-Token, die dem Parser mitteilen, dass diese Zeilen als Überschriften gedacht sind. Beachte, dass wir dieser Entscheidung einen Titel gegeben haben, der der Entscheidung entspricht, die wir treffen. Außerdem haben wir der Entscheidung einen etwas kryptischen Titel gegeben: "OPM1". Das ist nur ein Kurzcode, der uns hilft, den Teil des Systems zu kennzeichnen und zu verstehen, auf den sich die Entscheidung bezieht. In diesem Fall bedeutet "OPM1", dass dies die erste Entscheidung ist, die wir im Zusammenhang mit dem Betriebsmodell aufzeichnen.
Die Kopfzeile Status
unseres Datensatzes verrät uns, in welcher Phase des Lebenszyklus sich die Entscheidung befindet. Wenn du z.B. eine neue Entscheidung entwirfst, für die du eine Zustimmung brauchst, könntest du mit dem Status Proposed
beginnen. Oder wenn du erwägst, eine bestehende Entscheidung zu ändern, könntest du ihren Status auf Under Review
ändern. In unserem Fall haben wir die Entscheidung bereits für dich getroffen, also haben wir den Status auf Accepted
gesetzt.
Der Abschnitt Context
beschreibt das Problem, die Einschränkungen und den Hintergrund für die zu treffende Entscheidung. In unserem Fall wollen wir festhalten, dass wichtige Entscheidungen protokolliert werden müssen und warum das wichtig ist. Füge den folgenden Text (oder eine eigene Variante davon) in den Abschnitt Context
deines Datensatzes ein:
##
Context
A microservices architecture is complex and we'll need to make many
decisions. We'll need a way to keep track of the important decision
we make, so that we can revisit and re-evalute them in the future.
We'd prefer to use a lightweight, text-based solution so that we
don't have to install any new software tools.
Nachdem der Kontext feststeht, können wir die tatsächliche Entscheidung festhalten, die wir getroffen haben. Wir können einige der in Betracht gezogenen Alternativen sowie unsere Entscheidung für LADR auflisten. Füge Folgendes in den Abschnitt Decision
ein, um diese Tatsache zu dokumentieren:
##
Decision We've decided to use Michael Nygard's lightweight architectural decision record (LADR) format. LADR is text based and is lightweight enough to meet our needs. We'll keep each LADR record in its own text file and manage the files like code. We also considered the following alternative solutions:* Project management tooling (not selected, because we didn't want
to install tools)
*
Informal or "word of mouth" record keeping (not reliable)
Alles, was bleibt, ist die Dokumentation der Konsequenzen. In unserem Fall besteht eine der wichtigsten Konsequenzen darin, dass wir Zeit darauf verwenden müssen, unsere Entscheidungen zu dokumentieren und die Unterlagen zu verwalten. Lass uns das wie folgt festhalten:
##
Consequences*
We'll need to write decision records for key decisions*
We'll need a source code management solution to manage decision record files
Das ist alles, was du brauchst, um einen LADR zu schreiben. Das ist eine unglaublich nützliche Methode, um deine Gedanken festzuhalten und hat den zusätzlichen Vorteil, dass du gezwungen bist, von vornherein rationale, durchdachte Entscheidungen zu treffen. Während wir unsere Beispiel-Fluganwendung entwickeln, werden wir ein Protokoll über die wichtigsten Entscheidungen führen. Um Zeit zu sparen, werden wir nicht das gesamte Entscheidungsprotokoll aufschreiben. Stattdessen heben wir hervor, dass eine wichtige Entscheidung getroffen wurde, wie in der folgenden Notiz .
Eine detaillierte Version von findest du im GitHub-Repository dieses Buches.
Zusammenfassung
In diesem Kapitel haben wir einige grundlegende Konzepte für dieses Buch vorgestellt. Wir haben eine lockere Definition eines Microservices-Systems gegeben, die eine Reihe von drei wichtigen Merkmalen enthält. Wir haben die Verringerung der Koordinationskosten als den wichtigsten Vorteil von Microservices identifiziert. Außerdem haben wir untersucht, inwiefern Komplexität und Analyselähmung Herausforderungen für die Einführung von Microservices darstellen.
Um diese Herausforderungen zu meistern, haben wir das "Up and Running"-Microservices-Modell vorgestellt - eine meinungsbildende, präskriptive Implementierung, die den Lernprozess für die Implementierer beschleunigt. Wir haben die Aspekte des Modells und die Themen, die wir besprechen werden, erläutert. Zum Schluss haben wir das Konzept des architectural decision record (ADR) vorgestellt, das wir im gesamten Buch verwenden werden.
Nachdem wir den Überblick verloren haben, müssen wir nur noch das System aufbauen. In Kapitel 2 gehen wir zunächst darauf ein, wie Microservices funktionieren, und legen dabei einen besonderen Schwerpunkt auf die Teamkoordination.
Get Microservices: Auf und davon now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.