Bearbeiten

Freigeben über


Microservice-Architekturstil

Azure

Eine Microservicearchitektur besteht aus einer Sammlung kleiner, autonomer Dienste. Jeder Dienst ist eigenständig und sollte eine einzige Geschäftsfunktion in einem begrenzten Kontext implementieren. Ein begrenzter Kontext ist eine natürliche Unterteilung innerhalb eines Unternehmens und stellt eine explizite Grenze dar, in der ein Domänenmodell vorhanden ist.

Logisches Diagramm der Microservicearchitektur.

Was sind Microservices?

  • Microservices sind klein, unabhängig und lose gekoppelt. Ein Dienst kann von einem kleinen Entwicklerteam geschrieben und verwaltet werden.

  • Jeder Dienst stellt eine separate Codebasis dar, die von einem kleinen Entwicklungsteam verwaltet werden kann.

  • Die Dienste können unabhängig voneinander bereitgestellt werden. Ein Team kann einen vorhandenen Dienst aktualisieren, ohne die gesamte Anwendung neu erstellen und erneut bereitstellen zu müssen.

  • Die Dienste sind dafür zuständig, ihre eigenen Daten und ihren externen Zustand beizubehalten. Dies ist ein Unterschied zum herkömmlichen Modell, in dem eine separate Datenschicht die Datenpersistenz verwaltet.

  • Dienste kommunizieren über klar definierte APIs miteinander. Die internen Implementierungsdetails jedes Diensts werden für andere Dienste verborgen.

  • Sie unterstützen die Programmierung in mehreren Sprachen. Dienste müssen beispielsweise nicht den gleichen Technologiestapel, die gleichen Bibliotheken oder die gleichen Frameworks verwenden.

Abgesehen von den Diensten selbst gibt es in einer typischen Architektur für Microservices noch einige weitere Komponenten:

Verwaltung/Orchestrierung. Diese Komponente ist dafür zuständig, Dienste auf Knoten zu platzieren, Fehler zu ermitteln, die Dienste auf Knoten zu verteilen usw. In der Regel handelt es sich bei dieser Komponente nicht um eine benutzerdefinierte, sondern um eine handelsübliche Technologie (z. B. Kubernetes).

API-Gateway. Das API-Gateway ist der Einstiegspunkt für Clients. Statt die Dienste direkt aufzurufen, rufen Clients das API-Gateway auf, das den Aufruf an die geeigneten Dienste im Back-End weiterleitet.

Ein API-Gateway bietet u. a. folgende Vorteile:

  • Es entkoppelt die Clients von den Diensten. Für Dienste kann eine Versionierung oder Umgestaltung durchgeführt werden, ohne dass sämtliche Clients aktualisiert werden müssen.

  • Dienste können nicht webfähige Messagingprotokolle verwenden, z.B. AMQP.

  • Das API-Gateway kann weitere übergreifende Funktionen ausführen, beispielsweise Authentifizierung, Protokollierung, SSL-Terminierung und Lastenausgleich.

  • Vordefinierte Richtlinien, etwa für Drosselung, Zwischenspeicherung, Transformation oder Prüfung.

Vorteile

  • Flexibilität: Die unabhängige Bereitstellung von Microservices vereinfacht die Verwaltung von Fehlerkorrekturen und Featureveröffentlichungen. 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 Releaseprozess blockiert werden, wenn in einem Teil der Anwendung ein Fehler gefunden wird. Neue Features können sich verzögern, bis eine Fehlerbehebung integriert, getestet und veröffentlicht wurde.

  • Kleine, fokussierte Teams: Ein Microservice muss so kompakt sein, dass er von einem einzelnen Featureteam erstellt, getestet und bereitgestellt werden kann. Kleinere Teams sind agiler. Große Teams sind in der Regel weniger produktiv, da die Kommunikation langsamer ist, der Verwaltungsaufwand steigt und die Agilität abnimmt.

  • Kleine Codebasis. In einer monolithischen Anwendung werden Codeabhängigkeiten im Laufe der Zeit häufig unübersichtlich. Zum Hinzufügen eines neuen Features muss an vielen Stellen der Code bearbeitet werden. Da sich Microservices keinen Code und keine Datenspeicher teilen, enthält eine Microservices-Architektur weniger Abhängigkeiten und vereinfacht dadurch das Hinzufügen neuer Features.

  • Kombination verschiedener Technologien: Teams können sich für die Technologie entscheiden, die am besten zu ihrem Dienst passt, und eine Kombination aus geeigneten Technologiestapeln verwenden.

  • Fehlerisolation. Der Ausfall eines einzelnen Microservice hat nicht den Ausfall der gesamten Anwendung zur Folge – vorausgesetzt, die Upstream-Microservices sind für eine korrekte Behandlung von Ausfällen konzipiert. Sie können z. B. das Circuit Breaker-Muster (Trennschalter) implementieren oder Ihre Lösung so entwerfen, dass die Microservices miteinander kommunizieren, indem Sie asynchrone Messagingmuster verwenden.

  • Skalierbarkeit. Dienste können unabhängig skaliert werden. Dadurch lassen sich Subsysteme, die mehr Ressourcen benötigen, aufskalieren, ohne die gesamte Anwendung aufzuskalieren. Mit einem Orchestrator wie Kubernetes können Sie eine höhere Dichte von Diensten auf einem einzigen Host unterbringen, was eine effizientere Nutzung der Ressourcen ermöglicht.

  • Datenisolation: Schemaaktualisierungen sind wesentlich einfacher, da nur ein einzelner Microservice betroffen ist. Bei einer monolithischen Anwendung können sich Schemaaktualisierungen als echte Herausforderung erweisen, da verschiedene Teile der Anwendung unter Umständen die gleichen Daten nutzen, was jegliche Anpassung des Schemas zu einer riskanten Angelegenheit macht.

Herausforderungen

Die Vorteile von Microservices gibt es jedoch nicht umsonst. Im Anschluss finden Sie einige der Herausforderungen, die Sie vor der Erstellung einer Microservices-Architektur berücksichtigen sollten.

  • Komplexität. Eine Microserviceanwendung verfügt über mehr bewegliche Teile als die entsprechende monolithische Anwendung. Jeder Dienst für sich genommen ist einfacher, aber das System als Ganzes ist komplexer.

  • Entwicklung und Tests. Das Schreiben eines kleinen Diensts, der auf andere abhängige Dienste angewiesen 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 ebenfalls eine Herausforderung darstellen, insbesondere dann, 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. Dies gilt insbesondere für übergreifende Funktionen wie die Protokollierung.

  • Netzwerkkonflikte 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 (Dienst A ruft B auf, der wiederum C aufruft...), kann die zusätzliche Latenz zu einem Problem werden. Beim Entwurf der APIs sollten Sie größte Umsicht walten lassen. Vermeiden Sie überladene APIs, denken Sie über Serialisierungsformate nach, und suchen Sie nach Stellen, an denen Sie asynchrone Kommunikationsmuster (etwa Warteschlangenbasierter Lastenausgleich) verwenden können.

  • Datenintegrität. Jeder Microservice ist für die eigene Datenpersistenz zuständig. Dadurch kann die Sicherstellung der Datenkonsistenz über mehrere Dienste hinweg zu einer Herausforderung werden. Unterschiedliche Dienste speichern Daten zu unterschiedlichen Zeiten, mithilfe unterschiedlicher Technologien, wobei der Erfolgsfaktor variiert. Behalten mehrere Microservices das neue oder geänderte Datum bei, so wird die vollständige Datenänderung wahrscheinlich nicht als ACID-Transaktion betrachtet. Die Technik richtet sich stattdessen nach BASE (grundsätzlich verfügbar, vorläufiger Zustand und letztliche Konsistenz). Implementieren Sie die letztliche Konsistenz, wo immer möglich.

  • 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. Dienste können jederzeit aktualisiert werden, daher könnten ohne sorgfältigen Entwurf Probleme mit der Abwärts- oder Aufwärtskompatibilität entstehen.

  • Fähigkeiten: Microservices sind Systeme mit einem hohen Maß an Verteilung. Beurteilen Sie sehr genau, ob das Team über die notwendige Kompetenz und Erfahrung verfügt, erfolgreiche Arbeit zu leisten.

Bewährte Methoden

  • Modellieren Sie Dienste rund um die geschäftliche Domäne.

  • Dezentralisieren Sie alles. Einzelne Teams sind für den Entwurf und die Erstellung von Diensten verantwortlich. Vermeiden Sie die gemeinsame Nutzung von Code oder Datenschemas.

  • Die Datenspeicherung sollte ausschließlich in dem Dienst erfolgen, der die Daten besitzt. Verwenden Sie den optimalen Speicher für jeden Dienst- und Datentyp.

  • Dienste kommunizieren über sorgfältig entworfene APIs. Vermeiden Sie die Weitergabe von Implementierungsdetails. APIs sollten die Domäne modellieren, nicht die interne Implementierung des Diensts.

  • Vermeiden Sie eine Kopplung zwischen Diensten. Kopplung kann durch gemeinsam genutzte Datenbankschemas oder starre Kommunikationsprotokolle entstehen.

  • Lagern Sie übergreifende Funktionen wie Authentifizierung und SSL-Terminierung an das Gateway aus.

  • Informationen über die Domäne haben im Gateway nichts zu suchen. Das Gateway sollte Clientanforderungen ohne Kenntnis der Geschäftsregeln oder Domänenlogik verarbeiten und weiterleiten. Andernfalls wird das Gateway zu einer Abhängigkeit und kann zu Kopplung zwischen den Diensten führen.

  • Dienste sollten eine lose Kopplung und eine hohe funktionale Kohäsion aufweisen. Funktionen, die wahrscheinlich zusammen geändert werden, sollten auch zusammen gepackt und bereitgestellt werden. Wenn sie sich in verschiedenen Diensten befinden, sind diese Dienste letztlich eng gekoppelt, da eine Änderung in einem Dienst ein Update des anderen Diensts erfordert. Eine übermäßige Kommunikation zwischen zwei Diensten kann ein Symptom für enge Kopplung und geringe Kohäsion sein.

  • Isolieren Sie Fehler. Nutzen Sie Resilienzstrategien, um zu verhindern, dass Fehler in einem Dienst kaskadieren. Weitere Informationen finden Sie unter Resilienzmuster und Entwerfen zuverlässiger Anwendungen.

Nächste Schritte

Ausführliche Anleitungen zum Erstellen einer Microservices-Architektur in Azure finden unter Entwerfen, Erstellen und Betreiben von Microservices in Azure.