Microservices

Aus besserwiki.de

Eine Microservice-Architektur - eine Variante der serviceorientierten Architektur (SOA) - ordnet eine Anwendung als eine Sammlung von lose gekoppelten Diensten an. In einer Microservice-Architektur sind die Dienste feinkörnig und die Protokolle sind leichtgewichtig. Das Ziel ist, dass Teams ihre Dienste unabhängig von anderen zum Leben erwecken können. Durch die lose Kopplung werden alle Arten von Abhängigkeiten und die damit verbundenen Komplexitäten reduziert, da sich die Entwickler von Diensten nicht um die Nutzer des Dienstes kümmern müssen und ihre Änderungen nicht den Nutzern des Dienstes aufzwingen. Daher können Unternehmen, die Software entwickeln, schnell und umfangreich wachsen und Dienste von der Stange leichter nutzen. Die Kommunikationsanforderungen werden reduziert. Diese Vorteile sind mit Kosten für die Aufrechterhaltung der Entkopplung verbunden. Schnittstellen müssen sorgfältig entworfen und wie eine öffentliche API behandelt werden. Eine Technik, die angewandt wird, ist das Vorhandensein mehrerer Schnittstellen für ein und denselben Dienst oder mehrerer Versionen desselben Dienstes, um bestehende Nutzer des Codes nicht zu stören.

Microservices sind ein Architekturmuster der Informationstechnik, bei dem komplexe Anwendungssoftware aus unabhängigen Prozessen generiert wird, die untereinander mit sprachunabhängigen Programmierschnittstellen kommunizieren. Die Dienste sind weitgehend entkoppelt und erledigen eine kleine Aufgabe. So ermöglichen sie einen modularen Aufbau von Anwendungssoftware.

Einführung

Es gibt keine einheitliche Definition für Microservices. In der Branche hat sich im Laufe der Zeit ein Konsens herausgebildet. Einige der häufig zitierten definierenden Merkmale sind:

  • Dienste in einer Microservice-Architektur sind oft Prozesse, die über ein Netzwerk kommunizieren, um ein Ziel zu erreichen, wobei technologieunabhängige Protokolle wie HTTP verwendet werden.
  • Dienste sind um geschäftliche Fähigkeiten herum organisiert.
  • Dienste können mit verschiedenen Programmiersprachen, Datenbanken, Hardware- und Softwareumgebungen implementiert werden, je nachdem, was am besten passt.
  • Dienste sind klein, messaging-fähig, kontextgebunden, autonom entwickelt, unabhängig einsetzbar, dezentralisiert und werden mit automatisierten Prozessen erstellt und freigegeben.

Ein Microservice ist keine Schicht innerhalb einer monolithischen Anwendung (z. B. der Web-Controller oder das Backend-für-Frontend). Vielmehr ist er ein in sich geschlossenes Stück Geschäftsfunktionalität mit klaren Schnittstellen und kann durch seine eigenen internen Komponenten eine Schichtenarchitektur implementieren. Aus strategischer Sicht folgt die Microservice-Architektur im Wesentlichen der Unix-Philosophie "Do one thing and do it well". Martin Fowler beschreibt eine auf Microservices basierende Architektur mit den folgenden Eigenschaften:

  • Sie eignet sich für einen kontinuierlichen Softwareentwicklungsprozess. Eine Änderung an einem kleinen Teil der Anwendung erfordert nur den Neuaufbau und die Neuverteilung eines oder weniger Dienste.
  • Befolgt Prinzipien wie feinkörnige Schnittstellen (zu unabhängig einsetzbaren Diensten), geschäftsorientierte Entwicklung (z. B. domänenorientiertes Design).

Microservices-Architekturen werden häufig für Cloud-native Anwendungen, serverloses Computing und Anwendungen mit leichtgewichtiger Container-Bereitstellung eingesetzt. Laut Fowler sind aufgrund der großen Anzahl (im Vergleich zu monolithischen Anwendungsimplementierungen) von Diensten eine dezentrale kontinuierliche Bereitstellung und DevOps mit ganzheitlicher Dienstüberwachung erforderlich, um solche Anwendungen effektiv zu entwickeln, zu warten und zu betreiben. Eine Folge (und Begründung) dieses Ansatzes ist, dass die einzelnen Microservices individuell skaliert werden können. Beim monolithischen Ansatz müsste eine Anwendung, die drei Funktionen unterstützt, in ihrer Gesamtheit skaliert werden, selbst wenn nur eine dieser Funktionen eine Ressourcenbeschränkung hätte. Bei Microservices muss nur der Microservice skaliert werden, der die Funktion mit den Ressourcenbeschränkungen unterstützt, was Vorteile bei der Ressourcen- und Kostenoptimierung bietet.

Geschichte

Es gibt zahlreiche Behauptungen über den Ursprung des Begriffs Microservices. Während seiner Zeit als Vizepräsident von ThoughtWorks im Jahr 2004 begann Fred George mit der Arbeit an Prototyp-Architekturen, die auf den nach Jeff Bay benannten "Baysean Principles" basierten.

Bereits 2005 führte Peter Rodgers bei einem Vortrag auf der Web Services Edge-Konferenz den Begriff "Micro-Web-Services" ein. Entgegen konventionellem Denken und auf dem Höhepunkt der SOAP-SOA-Architektur-Hype-Kurve plädierte er für "REST-Services" und auf Folie Nr. 4 der Konferenzpräsentation erörtert er "Softwarekomponenten sind Micro-Web-Services". Er fährt fort: "Micro-Services werden mit Unix-ähnlichen Pipelines komponiert (das Web trifft Unix = echte lose Kopplung). Dienste können Dienste aufrufen (+Multiple Language Run-Times). Komplexe Service-Assemblies werden hinter einfachen URI-Schnittstellen abstrahiert. Jeder Dienst kann in jeder Granularität offengelegt werden." Er beschrieb, wie eine gut konzipierte Microservices-Plattform "die zugrundeliegenden architektonischen Prinzipien von Web- und REST-Diensten zusammen mit Unix-ähnlichem Scheduling und Pipelines anwendet, um radikale Flexibilität und verbesserte Einfachheit in serviceorientierten Architekturen zu bieten.

Rodgers' Arbeit begann 1999 mit dem Dexter-Forschungsprojekt bei Hewlett Packard Labs, dessen Ziel es war, den Code weniger spröde zu machen und große, komplexe Softwaresysteme robust gegenüber Änderungen zu gestalten. Letztlich führte dieser Forschungsweg zur Entwicklung des ressourcenorientierten Rechnens (ROC), einer verallgemeinerten Berechnungsabstraktion, von der REST eine spezielle Untermenge darstellt.

Im Jahr 2007 forderte Juval Löwy in seinen Schriften und Vorträgen den Aufbau von Systemen, in denen jede Klasse ein Dienst ist. Löwy erkannte, dass dies den Einsatz einer Technologie erforderte, die eine solche granulare Nutzung von Diensten unterstützen kann, und er erweiterte Windows Communication Foundation (WCF), um genau das zu tun, indem er jede Klasse als Dienst behandelte, während das herkömmliche Programmiermodell von Klassen beibehalten wurde.

Im Jahr 2005 schrieb Alistair Cockburn über die hexagonale Architektur (Software), ein Softwareentwurfsmuster, das zusammen mit den Microservices verwendet wird. Dieses Muster ermöglicht den Entwurf von Microservices, da es die Geschäftslogik schichtweise von den Hilfsdiensten isoliert, die benötigt werden, um den Microservice völlig unabhängig von anderen einzusetzen und auszuführen.

Auf einem Workshop von Softwarearchitekten, der im Mai 2011 in der Nähe von Venedig stattfand, wurde der Begriff "Microservice" verwendet, um zu beschreiben, was die Teilnehmer als einen gemeinsamen Architekturstil ansahen, den viele von ihnen in letzter Zeit erforscht hatten. Im Mai 2012 entschied sich dieselbe Gruppe für "Microservices" als den geeignetsten Namen. James Lewis präsentierte einige dieser Ideen als Fallstudie im März 2012 auf der 33. Degree in Krakau in Microservices - Java, the Unix Way, ebenso wie Fred George etwa zur gleichen Zeit. Adrian Cockcroft, ehemaliger Direktor für Cloud-Systeme bei Netflix, beschrieb diesen Ansatz als "fine-grained SOA" und leistete damit Pionierarbeit im Web-Maßstab, ebenso wie viele der anderen in diesem Artikel genannten Personen - Joe Walnes, Dan North, Evan Bottcher und Graham Tackley.

Microservices sind eine Spezialisierung eines Implementierungsansatzes für serviceorientierte Architekturen (SOA), die zum Aufbau flexibler, unabhängig einsetzbarer Softwaresysteme verwendet werden. Der Microservices-Ansatz ist die erste Umsetzung von SOA, die auf die Einführung von DevOps folgte und für den Aufbau kontinuierlich bereitgestellter Systeme immer beliebter wird.

Im Februar 2020 prognostizierte der Cloud Microservices Market Research Report, dass der globale Markt für Microservice-Architekturen von 2019 bis 2026 mit einer CAGR von 21,37 % wachsen und bis 2026 3,1 Milliarden US-Dollar erreichen wird.

Granularität der Dienste

Ein wichtiger Schritt bei der Definition einer Microservice-Architektur besteht darin, herauszufinden, wie groß ein einzelner Microservice sein muss. Hierfür gibt es keinen Konsens oder Lackmustest, da die richtige Antwort vom geschäftlichen und organisatorischen Kontext abhängt. Amazon beispielsweise verwendet eine serviceorientierte Architektur, bei der der Service oft 1:1 mit einem Team von 3 bis 10 Ingenieuren abgebildet wird. Die Terminologie sieht im Allgemeinen so aus: Dienste, die einer einzigen Aufgabe gewidmet sind, z. B. dem Aufruf eines bestimmten Backend-Systems oder der Durchführung einer bestimmten Art von Berechnung, werden als atomare Dienste bezeichnet. Analog dazu werden Dienste, die solche atomaren Dienste aufrufen, um eine Ausgabe zu konsolidieren, als zusammengesetzte Dienste bezeichnet.

Es gilt als schlechte Praxis, den Dienst zu klein zu machen, da dann der Laufzeit-Overhead und die betriebliche Komplexität die Vorteile des Ansatzes zunichte machen können. Wenn die Dinge zu feinkörnig werden, müssen alternative Ansätze in Erwägung gezogen werden - z. B. das Verpacken der Funktion als Bibliothek oder das Verschieben der Funktion in andere Microservices.

Wenn das domänengesteuerte Design bei der Modellierung der Domäne, für die das System entwickelt wird, eingesetzt wird, kann ein Microservice so klein wie ein Aggregat oder so groß wie ein begrenzter Kontext sein.

In der Diskussion über die Granularität von Microservices gibt es ein Spektrum, an dessen einem Ende die anämischen Services stehen, die keine große Anzahl von Verantwortlichkeiten haben, und am anderen Ende der modulare Monolith, der große Module eines Systems darstellt.

Vorteile

Die Vorteile der Zerlegung einer Anwendung in verschiedene kleinere Dienste sind zahlreich:

  • Modularität: Dadurch ist die Anwendung leichter zu verstehen, zu entwickeln und zu testen und wird widerstandsfähiger gegen Architekturerosion. Dieser Vorteil wird oft im Vergleich zur Komplexität monolithischer Architekturen angeführt.
  • Skalierbarkeit: Da Microservices unabhängig voneinander implementiert und bereitgestellt werden, d. h. sie laufen innerhalb unabhängiger Prozesse, können sie unabhängig überwacht und skaliert werden.
  • Integration von heterogenen Systemen und Altsystemen: Microservices gelten als praktikables Mittel zur Modernisierung bestehender monolithischer Softwareanwendungen. Es gibt Erfahrungsberichte von mehreren Unternehmen, die erfolgreich (Teile) ihrer bestehenden Software durch Microservices ersetzt haben oder dabei sind, dies zu tun. Der Prozess der Software-Modernisierung von Legacy-Anwendungen erfolgt in einem inkrementellen Ansatz.
  • Verteilte Entwicklung: Sie parallelisiert die Entwicklung, indem sie es kleinen autonomen Teams ermöglicht, ihre jeweiligen Dienste unabhängig zu entwickeln, bereitzustellen und zu skalieren. Außerdem kann sich die Architektur eines einzelnen Dienstes durch kontinuierliches Refactoring herausbilden. Microservice-basierte Architekturen erleichtern die kontinuierliche Integration, die kontinuierliche Bereitstellung und den Einsatz.

Kritik und Bedenken

Der Microservice-Ansatz wird wegen einer Reihe von Problemen kritisiert:

  • Dienste bilden Informationsbarrieren.
  • Inter-Service-Aufrufe über ein Netzwerk haben höhere Kosten in Form von Netzwerklatenz und Nachrichtenverarbeitungszeit als prozessinterne Aufrufe innerhalb eines monolithischen Serviceprozesses.
  • Tests und Bereitstellung sind komplizierter.
  • Das Verschieben von Verantwortlichkeiten zwischen den Diensten ist schwieriger. Dies kann die Kommunikation zwischen verschiedenen Teams, das Neuschreiben der Funktionalität in einer anderen Sprache oder die Anpassung an eine andere Infrastruktur erfordern. Microservices können jedoch unabhängig vom Rest der Anwendung bereitgestellt werden, während Teams, die an Monolithen arbeiten, sich für die gemeinsame Bereitstellung synchronisieren müssen.
  • Wenn man die Größe der Dienste als primären Strukturierungsmechanismus betrachtet, kann dies zu vielen Diensten führen, während die Alternative der internen Modularisierung zu einem einfacheren Design führen kann. Dies erfordert ein Verständnis der Gesamtarchitektur der Anwendungen und der Abhängigkeiten zwischen den Komponenten.
  • Zweiphasige Commits gelten als ein Anti-Pattern in Microservices-basierten Architekturen, da dies zu einer engeren Kopplung aller Teilnehmer innerhalb der Transaktion führt. Das Fehlen dieser Technologie verursacht jedoch umständliche Tänze, die von allen Transaktionsteilnehmern implementiert werden müssen, um die Datenkonsistenz zu wahren.
  • Die Entwicklung und der Support vieler Dienste sind schwieriger, wenn sie mit unterschiedlichen Werkzeugen und Technologien erstellt werden - dies ist insbesondere dann ein Problem, wenn Ingenieure häufig zwischen Projekten wechseln.
  • Das bei Microservices üblicherweise verwendete Protokoll (HTTP) wurde für öffentlich zugängliche Dienste entwickelt und eignet sich daher nicht für die Arbeit mit internen Microservices, die oft sehr zuverlässig sein müssen.
  • Die Dekompositionsmethodik ist zwar nicht spezifisch für Microservices, verwendet aber häufig eine funktionale Dekomposition, die nicht auf Änderungen der Anforderungen eingeht und gleichzeitig die Komplexität der Services erhöht.
  • Der Begriff Microservice selbst ist irreführend, da es nur Dienste gibt. Es gibt keine solide Definition dafür, wann ein Dienst ein Microservice ist und wann nicht.
  • Datenaggregation. Um einen vollständigen Überblick über ein funktionierendes System zu erhalten, müssen Datensätze aus den Microservice-Repositories extrahiert und in einem einzigen Schema zusammengeführt werden. So können beispielsweise operative Berichte erstellt werden, die mit einem einzigen Microservice-Repository nicht möglich sind.

Kognitive Belastung

Die Architektur bringt zusätzliche Komplexität und neue Probleme mit sich, die es zu bewältigen gilt, z. B. Netzwerklatenz, Entwurf von Nachrichtenformaten, Backup/Verfügbarkeit/Konsistenz (BAC), Lastausgleich und Fehlertoleranz. Alle diese Probleme müssen in großem Maßstab angegangen werden. Die Komplexität einer monolithischen Anwendung verschwindet nicht, wenn sie als eine Reihe von Microservices neu implementiert wird. Ein Teil der Komplexität wird in betriebliche Komplexität umgewandelt. Ein anderer Teil der Komplexität manifestiert sich in einem erhöhten Netzwerkverkehr, der zu einer langsameren Leistung führt. Außerdem hat eine Anwendung, die aus einer beliebigen Anzahl von Microservices besteht, eine größere Anzahl von Schnittstellen für den Zugriff auf ihr jeweiliges Ökosystem, was die architektonische Komplexität erhöht. Verschiedene Organisationsprinzipien (wie HATEOAS, die Dokumentation von Schnittstellen- und Datenmodellen über Swagger usw.) wurden angewandt, um die Auswirkungen dieser zusätzlichen Komplexität zu verringern.

Technologien

Computer-Microservices können in verschiedenen Programmiersprachen implementiert werden und unterschiedliche Infrastrukturen nutzen. Daher sind die wichtigsten technologischen Entscheidungen die Art und Weise, wie Microservices miteinander kommunizieren (synchron, asynchron, UI-Integration) und die für die Kommunikation verwendeten Protokolle (RESTful HTTP, Messaging, GraphQL ...). In einem traditionellen System wirken sich die meisten Technologieentscheidungen wie die Programmiersprache auf das gesamte System aus. Daher ist der Ansatz für die Auswahl von Technologien ein ganz anderer.

Die Eclipse Foundation hat eine Spezifikation für die Entwicklung von Microservices veröffentlicht: Eclipse MicroProfile.

Service-Mesh

In einem Service-Mesh ist jede Service-Instanz mit einer Instanz eines Reverse-Proxy-Servers gepaart, der als Service-Proxy, Sidecar-Proxy oder Sidecar bezeichnet wird. Die Dienstinstanz und der Sidecar-Proxy teilen sich einen Container, und die Container werden von einem Container-Orchestrierungstool wie Kubernetes, Nomad, Docker Swarm oder DC/OS verwaltet. Die Service-Proxys sind für die Kommunikation mit anderen Service-Instanzen zuständig und können Funktionen wie Service-(Instanz-)Erkennung, Lastausgleich, Authentifizierung und Autorisierung, sichere Kommunikation und andere unterstützen.

In einem Service-Mesh bilden die Service-Instanzen und ihre Sidecar-Proxys die Datenebene, die nicht nur die Datenverwaltung, sondern auch die Verarbeitung und Beantwortung von Anfragen umfasst. Das Service Mesh umfasst auch eine Steuerungsebene für die Verwaltung der Interaktion zwischen den Diensten, die durch ihre Sidecar-Proxys vermittelt wird. Es gibt mehrere Optionen für die Service-Mesh-Architektur: Open Service Mesh, Istio (ein Gemeinschaftsprojekt von Google, IBM und Lyft), Linkerd (ein CNCF-Projekt unter der Leitung von Buoyant), Consul (ein Produkt von HashiCorp) und viele andere in der Service-Mesh-Landschaft. Die Service-Mesh-Verwaltungsebene, Meshery, bietet Lebenszyklus-, Konfigurations- und Leistungsmanagement für Service-Mesh-Bereitstellungen.

Ein Vergleich der Plattformen

Die Implementierung einer Microservice-Architektur ist sehr schwierig. Es gibt viele Probleme (siehe Tabelle unten), die jede Microservice-Architektur berücksichtigen muss. Netflix hat ein Microservice-Framework entwickelt, um seine internen Anwendungen zu unterstützen, und dann viele Teile dieses Frameworks als Open Source zur Verfügung gestellt. Viele dieser Tools wurden über das Spring-Framework bekannt gemacht - sie wurden als Spring-basierte Tools unter dem Dach des Spring Cloud-Projekts neu implementiert. Die folgende Tabelle zeigt einen Vergleich zwischen einer implementierten Funktion aus dem Kubernetes-Ökosystem und einer entsprechenden Funktion aus der Spring Cloud-Welt. Ein bemerkenswerter Aspekt des Spring Cloud-Ökosystems ist, dass es sich um Java-basierte Technologien handelt, während Kubernetes eine polyglotte Laufzeitplattform ist.

Microservices betreffen Spring Cloud und Netflix OSS Kubernetes
Konfigurationsmanagement: Die Konfiguration für eine Microservice-Anwendung muss aus dem Code ausgelagert werden und über einen einfachen Serviceaufruf abrufbar sein. Spring Config Server und Netflix Archaius unterstützen beide einen Git-basierten Speicherort für die Konfiguration. Archaius unterstützt die Datentypisierung von Konfigurationen. Kubernetes ConfigMaps stellt die in etcd gespeicherte Konfiguration über Dienste zur Verfügung. Kubernetes Secrets unterstützt die dienstbasierte sichere Bereitstellung und Verwendung sensibler Konfigurationsinformationen (wie Kennwörter, Zertifikate usw.).
Service Discovery: Pflege einer Liste von Service-Instanzen, die für die Arbeit innerhalb einer Microservice-Domäne zur Verfügung stehen. Spring Cloud Eureka ermöglicht es Clients, sich zu registrieren, unterhält einen Heartbeat mit registrierten Clients und ordnet Servicenamen Hostnamen für Clients zu, die Services nach Servicenamen suchen. Kubernetes-Dienste ermöglichen die Registrierung von Instanzen von Diensten, die intern im Cluster verfügbar sind, während der Bereitstellung. Ingress ist ein Mechanismus, mit dem ein Dienst für Clients außerhalb des Clusters zugänglich gemacht werden kann.
Lastausgleich: Der Schlüssel zur Skalierung eines verteilten Systems ist die Möglichkeit, mehr als eine Instanz einer Komponente auszuführen. Die Last muss dann über einen Load Balancer auf diese Instanzen verteilt werden. Spring Cloud Ribbon bietet Service-Clients die Möglichkeit des Lastausgleichs über die Instanzen des Service. Kubernetes Service bietet die Möglichkeit des Lastausgleichs zwischen den Service-Instanzen. Dies ist nicht das Äquivalent zu dem, was Ribbon bietet.
API-Gateway: Die Granularität der von Microservices bereitgestellten APIs unterscheidet sich oft von den Anforderungen eines Service-Clients. API-Gateways implementieren Fassaden und bieten zusätzliche Dienste wie Proxying, Protokollübersetzung und andere Verwaltungsfunktionen. Spring Cloud Zuul bietet konfigurationsbasierte API-Fassaden Kubernetes Service und Ingress-Ressourcen, Istio, Ambassador sind Lösungen, die sowohl Nord-Süd- (Datenverkehr in das und aus dem Rechenzentrum) als auch Ost-West- (Datenverkehr zwischen Rechenzentren, Clouds oder Regionen) API-Gateway-Funktionen bieten. Zuul kann auch zusammen mit Kubernetes implementiert werden und ermöglicht die Konfiguration auf individueller Service-Ebene.
Sicherheitsbelange: Viele Sicherheitsbedenken werden an die API-Gateway-Implementierung weitergegeben. Bei verteilten Microservice-Anwendungen ist es sinnvoll, das Sicherheitsrad nicht neu zu erfinden und die Definition und Implementierung von Richtlinien in Komponenten zu ermöglichen, die von allen Diensten gemeinsam genutzt werden. Spring Cloud Security löst viele Sicherheitsbedenken durch Spring Cloud Zuul Das Kubernetes-Ökosystem bietet Service-Meshes wie Istio, die in der Lage sind, über ihre API-Gateway-Mechanismen Sicherheit zu bieten.
Zentralisierte Protokollierung: Es ist wichtig, eine zentralisierte Infrastruktur für die Erfassung und Analyse von Protokollen zu haben, um eine Vielzahl von Diensten zu verwalten, von denen viele auf verteilte Weise arbeiten. ELK-Stapel (Elasticsearch, LogStash, Kibana) EFK-Stapel (Elasticsearch, Fluentd, Kibana)
Zentralisierte Metriken: Ein zentraler Bereich, in dem der Zustand und die Leistung der einzelnen Dienste und des Gesamtsystems überwacht werden können, ist für einen ordnungsgemäßen Betrieb unerlässlich. Spring Spectator und Atlas Heapster, Prometheus und Grafana
Verteiltes Tracing: Per-Process-Logging und Metrik-Monitoring haben ihre Berechtigung, aber keines von beiden kann die komplexen Pfade rekonstruieren, die Transaktionen bei ihrer Ausbreitung über ein verteiltes System nehmen. Verteiltes Tracing ist ein wesentliches Werkzeug für eine Microservices-Plattform. Spring Cloud Sleuth Hawkular, Jaeger
Ausfallsicherheit und Fehlertoleranz: Verteilte Systeme müssen in der Lage sein, Ausfälle automatisch zu umgehen und Anfragen an die Service-Instanz weiterzuleiten, die eine optimale Antwort liefert. Spring Hystrix, Turbine und Ribbon Gesundheitsprüfung, Dienstnetze (Beispiel: Istio)
Automatische Skalierung und Selbstheilung: Verteilte Systeme reagieren auf eine höhere Last durch horizontale Skalierung: Die Plattform muss solche Bedingungen erkennen und selbsttätig darauf reagieren. Darüber hinaus muss das System Ausfälle erkennen und einen automatischen Neustart ohne Eingriffe des Benutzers durchführen können. - Zustandsprüfung, Selbstheilung und automatische Skalierung
Paketierung, Bereitstellung und Zeitplanung: Große Systeme erfordern eine robuste Paketverwaltung und Bereitstellungssysteme, um rollierende oder blau-grüne Bereitstellungen und ggf. Rollbacks zu verwalten. Ein Scheduler hilft bei der Entscheidung, auf welchem Ausführungsknoten ein neuer Satz von Diensten unter den aktuellen Bedingungen bereitgestellt werden kann. Spring Boot, Apache Maven. Das Spring Cloud-System verfügt nicht über einen echten Scheduler. Docker, Rkt, Kubernetes Scheduler & Bereitstellung, Helm
Auftragsverwaltung: geplante Berechnungen, die von einzelnen Benutzeranfragen getrennt sind. Spring Batch Kubernetes-Jobs und zeitgesteuerte Jobs
Singleton-Anwendung: Beschränkung eines bestimmten Dienstes auf die Ausführung als einzige Instanz dieses Dienstes im gesamten System. Spring-Cloud-Cluster Kubernetes-Pods

Typische Bestandteile einer Microservice-Architektur

Microservices benötigen sehr viel Infrastruktur, welche durch jeweils eigenständige Services implementiert wird.

Für die Lastverteilung externer HTTP-Anfragen von Clienten kommen Load-Balancer zum Einsatz. Statische Inhalte werden mittels eines Content Delivery Network ausgeliefert.

Die für die Geschäftsanforderungen zuständigen Services werden durch eine Reihe von Plattform- oder Infrastruktur-Services unterstützt. Diese übernehmen zentrale Aufgaben wie das Anwendungs- und Service-Monitoring, Logging-Webservices, Operations-Datenbanken, Konfigurationsmanagement, Verschlüsselung, Autorisierung und Authentifizierung, sowie Autoscaling, Softwareverteilung, A/B-Testing und Fault-Injection-Testing (FIT). Zudem gibt es zentrale Routingdienste, welche sich um die Zuordnung von URLs zu Instanzen mit den jeweiligen Diensten kümmern.

Hierzu kommen noch Dienste für die Datenpersistierung, insbesondere Caching, relationale Datenbanken und NoSQL-Datenbanken, sowie BLOB-Speicher für beliebige Dateien.

Nachteile

Microservices werden wegen einiger Merkmale kritisiert:

  • Die Abhängigkeiten zwischen den Microservices sind bei einer Microservicearchitektur nicht offensichtlich. Es ist oftmals unklar welche Microservices welche anderen Microservices in welcher Version benötigen.
  • Die verteilte Architektur erzeugt zusätzliche Komplexität, vor allem Netzwerk-Latenzen, Lastverteilung oder Fehlertoleranz (siehe dazu auch: Fallacies of Distributed Computing).
  • Da es mehr Systeme gibt die ausfallen können als bei monolithischen Services, steigt auch die Wahrscheinlichkeit, dass mindestens eine Komponente ausfällt. Wenn die Microservices wie üblich untereinander synchrone Abhängigkeiten haben, wirkt sich der Ausfall eines Microservices unmittelbar auf das Gesamtsystem aus.
  • Die Vielzahl an Services macht die Softwareverteilung und das Testen komplexer.
  • Der Aufwand für die Migration bestehender Systeme ist beträchtlich und bedeutet in der Regel auch eine Anpassung der Kommunikationskultur in den beteiligten Organisationen.
  • Das Logging und Monitoring wird komplexer, da mehrere Systeme involviert sind, welche ggf. unterschiedliche Logging- und Monitoringtechnologien einsetzen. Es sollten daher, zusätzlich zu dezentralen Logging- und Monitoringlösungen, zentrale Logging-, Monitoring- und OpsDB-Dienste eingesetzt werden.
  • Da es sich um ein potenziell weltweit verteiltes System handelt, müssen nicht nur unterschiedliche Zeitzonen der Client-Anwendungen, sondern auch unterschiedliche Zeitzonen der Hosts berücksichtigt werden. Eine Zeitsynchronisierung zwischen den Hosts (z. B. mittels NTP oder noch besser PTP) und die Verwendung passender Zeit-Bibliotheken (z. B. Joda Time oder Noda Time) wird damit zwingend notwendig.
  • Da es sich bei Microservices um eine verteilte Architektur handelt, muss aufgrund des CAP-Theorems zwischen Verfügbarkeit der Anwendung und der Datenkonsistenz gewählt werden. Monolithische Systeme können hingegen sowohl maximal verfügbar als auch maximal konsistent sein.
  • Da die Microservices in unterschiedlichen Programmiersprachen und Software-Stacks implementiert werden können, werden sie das oft auch, was zu den Nachteilen des polyglotten Programmierens führt: Das Know-how kann nicht mehr geteilt werden, es erhöhen sich die Anforderungen an die Entwicklungswerkzeuge und das Plattform-Management. Zudem muss die Funktionalität von Bibliotheken teilweise dupliziert werden.

Beispiele

Von folgenden Internetdiensten ist bekannt, dass sie Microservices benutzen:

Implementierungen

Jeder Microservice kann in einer anderen Programmiersprache mit einer anderen Technologie entwickelt werden. Also ist die Technologie für die Implementierung der einzelnen Microservices bei weitem nicht so wichtig wie die übergreifenden Technologien für die Integration und Kommunikation.

Neuere Entwicklungen

Inzwischen werden auch Abwandlungen dieses Architekturmusters beispielsweise in Form von Macroservices diskutiert. Ziel ist es, hierüber Nachteile von Microservices zu kompensieren, ohne die Nachteile eines Monolithen in Kauf nehmen zu müssen.