Monolithische und Microservicearchitekturen
Fabrikam hat den neuen Drohnendienst in seine vorhandene Anwendung integriert. Das Unternehmen erkennt, dass diese Lösung kein guter langfristiger Plan für seine Anwendung ist. Das vorhandene System ist eine monolithische Architektur. Was genau bedeutet das?
Was ist eine monolithische Architektur?
Eine monolithische Architektur ist eine Architektur, in der alle Komponenten für eine Anwendung innerhalb einer einzelnen Einheit zusammengestellt werden. Diese Einheit wird in der Regel innerhalb einer einzelnen Laufzeitinstanz der Anwendung eingeschränkt. Herkömmliche Anwendungen bestehen häufig aus einer Webschnittstelle, einer Dienst- und einer Datenebene. Bei einer monolithischen Architektur werden diese Ebenen in einer Instanz der Anwendung kombiniert.
Monolithische Architekturen sind häufig geeignete Lösungen für kleine Anwendungen, können aber unhandlich werden, wenn die Anwendung wächst. Was ursprünglich eine kleine Anwendung war, kann schnell zu einem komplexen System werden, das schwer zu skalieren, implementieren und erneuern ist.
Alle Dienste sind in einer einzelnen Einheit enthalten. Diese Anordnung führt zu Herausforderungen, wenn das Unternehmen und damit auch die nachfolgende Systemlast wächst. Beispiele hierfür sind:
- Das unabhängige Skalieren von Diensten gestaltet sich schwierig.
- Das Entwickeln und Verwalten von Bereitstellungen ist komplex, da die Codebasis wächst und die Implementierung von Releases und neuen Features verlangsamt wird.
- Die Architektur ist an einen einzelnen Technologiestapel gebunden, was Innovationen bei neuen Plattformen und SDKs einschränkt.
- Das Aktualisieren von Datenschemas wird immer schwieriger.
Diese Herausforderungen können bewältigt werden, indem alternative Architekturen wie eine Microservicearchitektur verwendet werden.
Was ist eine Microservicearchitektur?
Eine Microservicearchitektur besteht aus kleinen, unabhängigen und lose gekoppelten Diensten. Jeder Dienst kann unabhängig bereitgestellt und skaliert werden.
Ein Microservice ist so kompakt, dass er von einem kleinen Entwicklerteam geschrieben und verwaltet werden kann. Da Dienste unabhängig voneinander bereitgestellt werden können, kann ein Team einen vorhandenen Dienst aktualisieren, ohne die gesamte Anwendung neu erstellen und erneut bereitstellen zu müssen.
In der Regel ist jeder Dienst für seine eigenen Daten verantwortlich. Die Datenstruktur ist isoliert, sodass Upgrades oder Änderungen am Schema nicht von anderen Diensten abhängig sind. Anforderungen für Daten werden in der Regel über APIs verarbeitet und stellen ein klar definiertes und konsistentes Zugriffsmodell bereit. Die internen Implementierungsdetails werden für Consumer des Diensts verborgen.
Da jeder Dienst unabhängig ist, können verschiedene Technologiestapel, Frameworks und SDKs genutzt werden. Es ist üblich, dass sich Dienste auf REST-Aufrufe für die Dienst-zu-Dienst-Kommunikation verlassen, indem klar definierte APIs anstelle von Remoteprozeduraufrufen (RPC) oder anderen benutzerdefinierten Kommunikationsmethoden verwendet werden.
Microservicearchitekturen sind hinsichtlich der Technologie zwar agnostisch, allerdings werden für deren Implementierung häufig Container oder serverlose Technologien verwendet. Continuous Deployment (CD) und Continuous Integration (CI) werden häufig verwendet, um die Geschwindigkeit und Qualität von Entwicklungsaktivitäten zu steigern.
Vorteile einer Microservicearchitektur
Warum sollten Sie sich für eine Microservicearchitektur entscheiden? Eine Microservicearchitektur bietet einige wesentliche Vorteile:
- Agilität
- Kompakter Code, kleine Teams
- Kombination verschiedener Technologien
- Resilienz
- Skalierbarkeit
- Datenisolation
Agilität
Die unabhängige Bereitstellung von Microservices vereinfacht die Verwaltung von Fehlerkorrekturen und Featurereleases. Sie können einen Dienst aktualisieren, ohne die gesamte Anwendung erneut bereitstellen zu müssen, und im Problemfall einen Rollback für ein Update ausführen. In vielen herkömmlichen Anwendungen kann der gesamte Freigabeprozess blockiert werden, wenn ein Fehler in einem Teil der Anwendung gefunden wird. In der Folge werden möglicherweise neue Features angehalten, die darauf warten, dass eine Fehlerbehebung integriert, getestet und veröffentlicht wird.
Kompakter Code, kleine Teams
Ein Microservice muss so kompakt sein, dass er von einem einzelnen Featureteam erstellt, getestet und bereitgestellt werden kann. Eine kompakte Codebasis ist leichter nachvollziehbar. In einer großen monolithischen Anwendung werden Codeabhängigkeiten tendenziell im Laufe der Zeit verwickelt. Zum Hinzufügen eines neuen Features muss an vielen Stellen der Code bearbeitet werden. Eine Microservices-Architektur minimiert die Abhängigkeiten, da weder Code noch Datenspeicher geteilt werden. Dies vereinfacht das Hinzufügen neuer Features.
Kleinere Teams sind außerdem flexibler. Eine Regel besagt, dass ein Team zu groß ist, wenn zwei Pizzen nicht ausreichen, um das gesamte Team zu versorgen. Das ist natürlich keine exakte Metrik und hängt vom Appetit der Teammitglieder ab! Entscheidend ist jedoch, dass große Gruppen in der Regel weniger produktiv sind, da sich die Kommunikation verlangsamt, der Verwaltungsaufwand steigt und die Agilität abnimmt.
Kombination verschiedener Technologien
Teams können die Technologie auswählen, die sich für ihren Dienst am besten eignet. Sie können je nach Bedarf eine Mischung aus Technologiestapeln verwenden. Jedes Team kann die Technologien weiterentwickeln, die den Dienst unabhängig voneinander unterstützen. Aufgrund dieser Unabhängigkeit können Dienste verschiedene Entwicklungssprachen, Clouddienste, SDKs und vieles mehr verwenden. Teams können die besten Optionen für ihren Dienst auswählen, während gleichzeitig externe Auswirkungen auf die Consumer des Dienstes minimiert werden.
Resilienz
Der Ausfall eines einzelnen Microservice hat nicht den Ausfall der gesamten Anwendung zur Folge – vorausgesetzt, die Upstreammicroservices sind für eine korrekte Behandlung von Ausfällen konzipiert (beispielsweise durch die Implementierung des Trennschalter-Musters). Für Ihre Endbenutzer oder Dienstbenutzer liegt der Vorteil in der ständigen Verfügbarkeit Ihrer Anwendung.
Skalierbarkeit
In einer Microservicesarchitektur kann jeder Microservice unabhängig skaliert werden. Sie können Subsysteme, die mehr Ressourcen benötigen, horizontal hochskalieren, ohne die gesamte Anwendung hochzuskalieren. Durch diese Anordnung wird die Gesamtleistung Ihrer Anwendung verbessert. Außerdem trägt dies zur Kostenminimierung bei. Sie können ausschließlich den Diensten, die Sie benötigen, mehr Ressourcen hinzufügen, anstatt ihre gesamte Anwendung zentral hochzuskalieren.
Datenisolation
Eine Microservicesarchitektur verbessert die Fähigkeit, Datenschemaaktualisierungen durchführen zu können, da nur ein einzelner Microservice betroffen ist. In einer monolithischen Anwendung können Schemaaktualisierungen zu einer Herausforderung werden. Unterschiedliche Teile der Anwendung könnten die gleichen Daten berühren, sodass Änderungen am Schema riskant sind. Bei einer Microservicesarchitektur können Sie ein Schema aktualisieren, aber die API-Oberfläche intakt halten. Die Dienstconsumer machen dann unabhängig von der zugrunde liegenden Datenarchitektur dieselbe Erfahrung.
Potenzielle Herausforderungen einer Microservicesarchitektur
Eine Microservicesarchitektur bietet viele Vorteile, ist aber kein Allheilmittel. Eine Microservicesarchitektur bringt ihre eigenen Herausforderungen mit sich:
- Komplexität
- Entwicklung und Testen
- Unzureichende Governance
- Netzwerküberlastung und -latenz
- Datenintegrität
- Verwaltung
- Versionsverwaltung
- Fähigkeiten
Komplexität
Eine Microserviceanwendung verfügt über mehr bewegliche Teile als die entsprechende monolithische Anwendung. Jeder Dienst ist einfacher, das System als Ganzes aber komplexer. Mithilfe von Dienstermittlung, Orchestrierung und Automatisierungstools können in der gesamten Anwendung mehr Elemente verwaltet werden.
Entwicklung und Testen
Das Schreiben eines kleinen Diensts, der von anderen abhängigen Diensten abhängig ist, erfordert eine andere Herangehensweise als das Schreiben einer herkömmlichen monolithischen oder mehrschichtigen Anwendung. Vorhandene Tools sind nicht immer für die Arbeit mit Dienstabhängigkeiten geeignet. Refactoring über Dienstgrenzen hinweg kann schwierig sein. Das Testen von Dienstabhängigkeiten kann insbesondere dann eine Herausforderung darstellen, wenn sich die Anwendung schnell weiterentwickelt.
Unzureichende Governance
Der dezentralisierte Ansatz für die Erstellung von Microservices bietet einige Vorteile, kann jedoch auch zu Problemen führen. Es könnte passieren, dass so viele verschiedene Sprachen und Frameworks verwendet werden, dass die Verwaltung der Anwendung schwierig wird. Es empfiehlt sich möglicherweise, einige für das gesamte Projekt gültige Standards zu etablieren, ohne die Agilität der Teams zu sehr einzuschränken. Die Notwendigkeit einheitlicher Standards gilt insbesondere für übergreifende Funktionen wie die Protokollierung und Metriken.
Netzwerküberlastung und -latenz
Die Verwendung vieler kleiner, genau abgestimmter Dienste kann zu einer vermehrten Kommunikation zwischen den Diensten führen. Wenn die Kette der Dienstabhängigkeiten zu lang wird (z. B. Dienst A ruft B auf, der wiederum C aufruft), kann die zusätzliche Wartezeit dieser Netzwerkaufrufe zu einem Problem werden. Entwerfen Sie Ihre APIs sorgfältig. Vermeiden Sie überladene APIs, denken Sie über Serialisierungsformate nach, und suchen Sie nach Stellen, an denen Sie asynchrone Kommunikationsmuster verwenden können.
Datenintegrität
Jeder Microservice ist für die eigene Datenpersistenz zuständig. Dadurch kann die Sicherstellung der Datenkonsistenz zu einer Herausforderung werden. Implementieren Sie die letztliche Konsistenz überall dort, wo dies möglich ist. Es kann auch sein, dass Sie Daten doppelt und eine ausgedehnte Datenarchitektur erhalten. In dieser Situation steigen möglicherweise die Speicherkosten und die Kosten für die Datenplattformdienste mit Dienst- und Datenduplikaten.
Verwaltung
Für den erfolgreichen Einsatz von Microservices ist eine ausgereifte DevOps-Kultur erforderlich. Die korrelierte Protokollierung über Dienste hinweg kann eine Herausforderung sein. In der Regel muss die Protokollierung mehrere Dienstaufrufe für einen einzigen Benutzervorgang korrelieren.
Versionsverwaltung
Dienstupdates dürfen nicht zu Unterbrechungen bei abhängigen Diensten führen. Einige Dienste könnten jederzeit aktualisiert werden. Ohne einen sorgfältigen Entwurf können daher Probleme mit der Abwärts- oder Aufwärtskompatibilität entstehen. Wenn bei Diensten bei der Einführung neuer API-Versionen Verzögerungen auftreten, können sich die für ältere APIs erforderlichen Ressourcen und der Wartungsaufwand erhöhen.
Fähigkeiten
Microservices sind Systeme mit einem hohen Maß an Verteilung. Zum Entwickeln, Verwalten und Warten dieser verteilten Systeme sind oft unterschiedliche Fähigkeiten erforderlich. Beurteilen Sie sehr genau, ob das Team über die notwendige Kompetenz und Erfahrung verfügt, um erfolgreiche Arbeit leisten zu können. Geben Sie Ihrem Team ausreichend Zeit, um sich weiterentwickeln zu können.
Wann sollten Sie sich für eine Microservicesarchitektur entscheiden?
In welchen Situationen eignet sich eine Microservicesarchitektur aufgrund dieser Hintergrundinformationen am besten?
- Große Anwendungen, für die eine hohe Releasegeschwindigkeit erforderlich ist.
- Komplexe Anwendungen, die hochgradig skalierbar sein müssen
- Anwendungen mit umfangreichen Domänen oder vielen Unterdomänen
- Eine Organisation, die aus vielen kleinen Entwicklungsteams besteht