it-swarm.com.de

Microservices orchestrieren

Was ist das Standardmuster für die Orchestrierung von Microservices?

Wenn ein Microservice nur über seine eigene Domäne Bescheid weiß, es jedoch einen Datenfluss gibt, der die Interaktion mehrerer Dienste erfordert, wie soll dann vorgegangen werden?

Nehmen wir an, wir haben so etwas:

  • Fakturierung
  • Sendung

Nehmen wir an, die Rechnung sollte erstellt werden, sobald eine Bestellung versandt wurde. 

Irgendwo drückt jemand eine Taste in einer grafischen Benutzeroberfläche: "Ich bin fertig, lass uns das tun!" des Rechnungsdienstes und nennt das einfach.

Aber wie gehen Menschen in dieser schönen neuen Welt der Mikrodienste damit um?

Ich verstehe, dass dies als stark meinungsbezogen angesehen werden kann. Aber es gibt eine konkrete Seite, da Microservices das oben genannte nicht tun sollen. Es muss also ein "Was soll es per definitionem tun", das nicht meinungsbasiert ist.

Schießen.

162
Roger Johansson

Das Buch Building Microservices beschreibt ausführlich die Stile, die von @RogerAlsing in seiner Antwort erwähnt wurden.

Auf Seite 43 unter Orchestration vs Choreography heißt es:

Während wir anfangen, immer komplexere Logik zu modellieren, müssen wir uns mit dem Problem der Verwaltung von Geschäftsprozessen befassen, die über die Grenzen einzelner Services hinausgehen. Und mit Microservices werden wir diese Grenze früher als gewöhnlich erreichen. [...] Wenn es darum geht, diesen Fluss tatsächlich zu implementieren, können wir zwei Arten von Architektur verfolgen. Bei der Orchestrierung verlassen wir uns auf ein zentrales Gehirn, um den Prozess zu steuern und voranzutreiben, ähnlich wie der Dirigent in einem Orchester. Mit der Choreografie informieren wir jeden Teil des Systems über seinen Job und lassen ihn die Details herausarbeiten, wie Tänzer, die sich zurechtfinden und in einem Ballett auf andere reagieren.

Das Buch erklärt dann die beiden Stile. Der Orchestrierungsstil entspricht eher der SOA Idee von Orchestrierungs-/Aufgabendiensten , wohingegen der Choreografierungsstil der dummen Pipes und intelligenten Endpunkten entspricht in Martin Fowlers Artikel erwähnt.

Orchestrierungsstil

Unter diesem Stil erwähnt das obige Buch:

Überlegen wir uns, wie eine Orchestrierungslösung für diesen Flow aussehen würde. Hier wäre es wahrscheinlich am einfachsten, wenn unser Kundenservice als zentrales Gehirn fungiert. Bei der Erstellung wird über eine Reihe von Anforderungs-/Antwortanrufen mit der Treuepunktebank, dem E-Mail-Dienst und dem Postdienst [...] gesprochen. Der Kundendienst selbst kann dann verfolgen, wo sich ein Kunde in diesem Prozess befindet. Es kann überprüfen, ob das Kundenkonto eingerichtet wurde, ob die E-Mail gesendet wurde oder ob die Post zugestellt wurde. Wir nehmen das Flussdiagramm [...] und modellieren es direkt in Code. Wir könnten sogar Tools verwenden, die dies für uns implementieren, möglicherweise mithilfe einer geeigneten Regelengine. Zu diesem Zweck gibt es kommerzielle Tools in Form von Geschäftsprozessmodellierungssoftware. Unter der Annahme, dass wir synchrone Anfragen/Antworten verwenden, könnten wir sogar wissen, ob [...] jede Phase funktioniert hat. Der Nachteil dieses Orchestrierungsansatzes ist, dass der Kundenservice zu einer zentralen Kontrollinstanz werden kann. Es kann zur Drehscheibe in einem Web werden und zu einem zentralen Punkt, an dem die Logik zu leben beginnt. Ich habe gesehen, dass dieser Ansatz zu einer kleinen Anzahl intelligenter "Gott" -Dienste führt, die anämischen CRUD-basierten Diensten mitteilen, was zu tun ist.

Hinweis: Ich nehme an, wenn der Autor Werkzeuge erwähnt, bezieht er sich auf etwas wie BPM (zB Aktivität , Apache ODE) , Camunda ). Tatsächlich bietet die Workflow Patterns Website eine beeindruckende Sammlung von Mustern für diese Art der Orchestrierung und bietet auch Bewertungsdetails zu verschiedenen Tools von Anbietern, die bei der Implementierung auf diese Weise helfen. Ich glaube nicht, dass der Autor impliziert, dass man eines dieser Tools verwenden muss, um diesen Integrationsstil zu implementieren. Es könnten jedoch auch andere einfache Orchestrierungs-Frameworks verwendet werden, z. Spring Integration , Apache Camel oder Mule ESB

Allerdings andere Bücher habe ich zum Thema Microservices gelesen und im Allgemeinen scheinen die meisten Artikel, die ich im Web gefunden habe, diesen Ansatz abzulehnen von Orchestrierung und stattdessen Schlagen Sie die Verwendung des nächsten vor.

Choreografiestil

Unter Choreografiestil sagt der Autor:

Mit einem choreografierten Ansatz könnten wir stattdessen einfach den Kundenservice ein Ereignis auf asynchrone Weise ausgeben lassen, indem er sagt, dass der Kunde erstellt wurde. Der E-Mail-Dienst, der Postdienst und die Treuepunktebank abonnieren diese Ereignisse dann einfach und reagieren entsprechend [...]. Dieser Ansatz ist deutlich entkoppelt. Wenn ein anderer Dienst benötigt wird, um einen Kunden zu erstellen, muss er nur die Ereignisse abonnieren und bei Bedarf seine Arbeit erledigen. Der Nachteil ist, dass die explizite Sicht auf den Geschäftsprozess, den wir in [dem Workflow] sehen, jetzt nur implizit in unserem System wiedergegeben wird. [...] Dies bedeutet, dass zusätzliche Arbeit erforderlich ist, um sicherzustellen, dass Sie die richtigen Dinge überwachen und verfolgen können passierte. Möchten Sie beispielsweise wissen, ob die Treuepunkte-Bank einen Fehler aufweist und aus irgendeinem Grund nicht das richtige Konto eingerichtet hat? Ein Ansatz, mit dem ich mich gerne befasse, besteht darin, ein Überwachungssystem zu erstellen, das explizit der Ansicht des Geschäftsprozesses in [dem Workflow] entspricht, dann aber nachverfolgt, was die einzelnen Services als unabhängige Entitäten tun, sodass Sie seltsame Ausnahmen auf dem Server abbilden können expliziterer Prozessablauf. Das [Flussdiagramm] [...] ist nicht die treibende Kraft, sondern nur eine Linse, durch die wir sehen können, wie sich das System verhält. Im Allgemeinen habe ich festgestellt, dass Systeme, die eher zum choreografierten Ansatz tendieren, lockerer gekoppelt sind und flexibler und veränderungsfähiger sind. Sie müssen jedoch zusätzliche Arbeit leisten, um die Prozesse über Systemgrenzen hinweg zu überwachen und zu verfolgen. Ich habe festgestellt, dass die am stärksten orchestrierten Implementierungen extrem spröde sind und höhere Änderungskosten verursachen. In diesem Sinne bevorzuge ich ein choreografiertes System, bei dem jeder Dienst intelligent genug ist, um seine Rolle im gesamten Tanz zu verstehen.

Hinweis: Bis heute bin ich mir nicht sicher, ob Choreografie nur ein anderer Name für ereignisgesteuerte Architektur (EDA) ist, aber wenn EDA nur eine Möglichkeit ist, dies zu tun, welche anderen Möglichkeiten gibt es? (Siehe auch Was meinen Sie mit "ereignisgesteuert"? und Die Bedeutungen ereignisgesteuerter Architektur ). Außerdem scheinen Dinge wie CQRS und EvenSourcing viel mit diesem Architekturstil zu tun zu haben, oder?

Nun, danach kommt der Spaß. Das Microservices-Buch geht nicht davon aus, dass Microservices mit REST implementiert werden. Tatsächlich werden im nächsten Abschnitt des Buches RPC- und SOA-basierte Lösungen und schließlich REST betrachtet. Ein wichtiger Punkt hierbei ist, dass Microservices nicht REST impliziert.

Also, was ist mit HATEOAS?

Wenn wir nun dem REST-Ansatz folgen möchten, können wir HATEOAS nicht ignorieren, oder Roy Fielding freut sich, in seinem Blog zu sagen, dass unsere Lösung nicht wirklich REST ist. Siehe seinen Blogeintrag auf REST-API muss hypertextgesteuert sein :

Ich bin frustriert über die Anzahl der Leute, die eine HTTP-basierte Schnittstelle als REST API aufrufen. Was muss getan werden, um den REST Architekturstil zu verdeutlichen? die Vorstellung, dass Hypertext eine Einschränkung ist? Mit anderen Worten, wenn die Engine des Anwendungsstatus (und damit die API) nicht durch Hypertext gesteuert wird, kann sie nicht REST-konform sein und kann keine REST API. Periode. Gibt es irgendwo ein kaputtes Handbuch, das repariert werden muss?

Wie Sie sehen, ist Fielding der Ansicht, dass Sie ohne HATEOAS keine wirklich REST-fähigen Anwendungen erstellen. Für Fielding ist HATEOAS der richtige Weg, wenn es darum geht, Dienste zu orchestrieren. Ich lerne gerade das alles, aber für mich definiert HATEOAS nicht klar, wer oder was die treibende Kraft hinter dem tatsächlichen Folgen der Links ist. In einer Benutzeroberfläche, die der Benutzer sein könnte, aber bei Computer-zu-Computer-Interaktionen muss dies vermutlich von einem übergeordneten Dienst ausgeführt werden.

Laut HATEOAS muss der API-Konsument nur den Link wirklich kennen, der die Kommunikation mit dem Server initiiert (z. B. POST/order). Ab diesem Zeitpunkt REST führt den Flow aus, da die zurückgegebene Ressource in der Antwort auf diesen Endpunkt die Links zu den nächsten möglichen Zuständen enthält. Der API-Consumer entscheidet dann, welchem ​​Link er folgt, und verschiebt die Anwendung in den nächsten Zustand.

Ungeachtet dessen, wie cool das klingt, muss der Client immer noch wissen, ob der Link POSTED, PUTED, GETED, PATCHED usw. sein muss. Außerdem muss der Client immer noch entscheiden, welche Nutzlast übergeben werden soll. Der Client muss weiterhin wissen, was zu tun ist, wenn dies fehlschlägt (erneut versuchen, kompensieren, abbrechen usw.).

Ich bin ziemlich neu in all dem, aber aus Sicht von HATEOAs ist dieser Client oder API-Kunde für mich ein Service von hoher Qualität. Wenn wir es aus der Perspektive eines Menschen betrachten, können Sie sich vorstellen, dass ein Endbenutzer auf einer Webseite entscheidet, welchen Links er folgen soll. Der Programmierer der Webseite musste jedoch entscheiden, mit welcher Methode und auf welche Weise die Links aufgerufen werden sollen Nutzlast zu übergeben. Meiner Meinung nach übernimmt der Computer in einer Computer-zu-Computer-Interaktion die Rolle des Endbenutzers. Dies ist wiederum ein so genannter Orchestrierungsdienst.

Ich nehme an, wir können HATEOAS entweder für Orchestrierung oder Choreografie verwenden.

Das API-Gateway-Muster

Ein weiteres interessantes Muster wird von Chris Richardson vorgeschlagen, der auch das vorschlug, was er API Gateway Pattern nannte.

In einer monolithischen Architektur stellen Clients der Anwendung, wie z. B. Webbrowser und native Anwendungen, HTTP-Anforderungen über einen Lastenausgleich an eine von N identischen Instanzen der Anwendung. In einer Microservice-Architektur wurde der Monolith jedoch durch eine Sammlung von Services ersetzt. Folglich ist eine wichtige Frage, die wir beantworten müssen, mit was interagieren die Kunden?

Ein Anwendungsclient, z. B. eine native mobile Anwendung, kann REST-konforme HTTP-Anforderungen an die einzelnen Dienste senden. Es ist jedoch wahrscheinlich, dass die APIs der einzelnen Dienste und die von den Clients benötigten Daten in ihrer Granularität erheblich voneinander abweichen. Zum Beispiel kann das Anzeigen einer Webseite möglicherweise Anrufe bei einer großen Anzahl von Diensten erfordern. Amazon.com zum Beispiel beschreibt wie einige Seiten Aufrufe von mehr als 100 Diensten erfordern. Selbst über eine Hochgeschwindigkeits-Internetverbindung so viele Anfragen zu stellen, geschweige denn über ein Mobilfunknetz mit geringerer Bandbreite und höherer Latenz, wäre sehr ineffizient und würde zu einer schlechten Benutzererfahrung führen.

Ein viel besserer Ansatz besteht darin, dass Clients eine geringe Anzahl von Anforderungen pro Seite, möglicherweise nur eine, über das Internet an einen Front-End-Server senden, der als API-Gateway bezeichnet wird.

Das API-Gateway befindet sich zwischen den Clients der Anwendung und den Microservices. Es bietet APIs, die auf den Client zugeschnitten sind. Das API-Gateway bietet mobilen Clients eine grobkörnige API und Desktop-Clients, die ein Hochleistungsnetzwerk verwenden, eine feinkörnigere API. In diesem Beispiel senden die Desktop-Clients mehrere Anforderungen zum Abrufen von Informationen zu einem Produkt, während ein mobiler Client eine einzelne Anforderung sendet.

Das API-Gateway verarbeitet eingehende Anforderungen, indem es über das Hochleistungs-LAN Anforderungen an eine Reihe von Mikrodiensten sendet. Netflix zum Beispiel beschreibt wie sich jede Anfrage auf durchschnittlich sechs Backend-Dienste verteilt. In diesem Beispiel werden fein abgestimmte Anforderungen von einem Desktop-Client einfach an den entsprechenden Dienst weitergeleitet, während jede grob abgestimmte Anforderung von einem mobilen Client durch Zusammenfassen der Ergebnisse des Aufrufs mehrerer Dienste verarbeitet wird.

Das API-Gateway optimiert nicht nur die Kommunikation zwischen Clients und der Anwendung, sondern kapselt auch die Details der Microservices. Dadurch können sich die Microservices weiterentwickeln, ohne die Kunden zu beeinträchtigen. Beispielsweise könnten zwei Mikrodienste zusammengeführt werden. Ein anderer Mikrodienst ist möglicherweise in zwei oder mehr Dienste unterteilt. Nur das API-Gateway muss aktualisiert werden, um diese Änderungen widerzuspiegeln. Die Kunden bleiben unberührt.

Nachdem wir uns angesehen haben, wie das API-Gateway zwischen der Anwendung und ihren Clients vermittelt, wollen wir uns nun ansehen, wie die Kommunikation zwischen Mikrodiensten implementiert wird.

Dies klingt dem oben erwähnten Orchestrierungsstil ziemlich ähnlich, nur mit einer etwas anderen Absicht. In diesem Fall geht es anscheinend nur um die Leistung und die Vereinfachung von Interaktionen.

Weiterführende Literatur

Es gibt eine große Reihe von Artikeln, die kürzlich im NGINX-Blog veröffentlicht wurden. Ich empfehle, mich eingehender mit all diesen Konzepten zu befassen:

281
Edwin Dalorzo

Versuch, die verschiedenen Ansätze hier zusammenzufassen.

Domain-Ereignisse

Der vorherrschende Ansatz hierfür scheint die Verwendung von Domänenereignissen zu sein, bei denen jeder Dienst Ereignisse über das Geschehene veröffentlicht und andere Dienste diese Ereignisse abonnieren können. Dies scheint mit dem Konzept der intelligenten Endpunkte, dumm, zu tun zu haben Pipes, die von Martin Fowler hier beschrieben werden: http://martinfowler.com/articles/microservices.html#SmartEndpointsAndDumbPipes

Domain events

Proxy

Ein anderer Ansatz, der anscheinend allgemein erscheint, besteht darin, den Geschäftsablauf in seinen eigenen Service einzubinden. Dort, wo der Proxy die Interaktion zwischen den Microservices koordiniert, wie in der folgenden Abbildung dargestellt:

Proxies.

30
Roger Johansson

Wie unterscheidet sich also die Orchestrierung von Microservices von der Orchestrierung alter SOA -Dienste, die nicht "micro" sind? Überhaupt nicht viel. 

Microservices kommunizieren normalerweise über http (REST) ​​oder Messaging/Ereignisse. Orchestrierung ist häufig mit Orchestrierungsplattformen verknüpft, mit denen Sie eine Skriptinteraktion zwischen Diensten erstellen können, um Workflows zu automatisieren. In den alten SOA Tagen verwendeten diese Plattformen WS-BPEL. Heutige Tools verwenden kein BPEL. Beispiele für moderne Orchestrierungsprodukte: Netflix Conductor, Camunda, Zeebe, Azure Logic Apps, Baker. 

Denken Sie daran, dass Orchestrierung ein zusammengesetztes Muster ist, das mehrere Funktionen zum Erstellen komplexer Zusammenstellungen von Services bietet. Microservices werden häufiger als Dienste betrachtet, die nicht an komplexen Kompositionen teilnehmen sollten, sondern eher autonom sein sollten. 

Ich kann einen Microservice sehen, der in einem orchestrierten Workflow aufgerufen wird, um einige einfache Abläufe durchzuführen, aber ich sehe keinen Microservice als Orchestrator-Dienst, der häufig Mechanismen wie das Kompensieren von Transaktionen und das Verwalten von Zuständen (Dehydration) verwendet. 

6
Paulo Merson

Sie haben also zwei Dienste:

  1. Rechnungsmikro-Service
  2. Versand Mikroservice

Im wirklichen Leben hätten Sie etwas, wo Sie den Ordnungszustand haben. Nennen wir es Bestellservice. Als Nächstes haben Sie Anwendungsfälle für die Auftragsabwicklung, die wissen, was zu tun ist, wenn die Bestellung von einem Zustand in einen anderen übergeht. Alle diese Dienste enthalten bestimmte Daten, und jetzt brauchen Sie etwas anderes, das die gesamte Koordination übernimmt. Das könnte sein:

  • Eine einfache GUI, die alle Ihre Dienste kennt und die Anwendungsfälle implementiert ("Ich bin fertig", ruft den Versanddienst an)
  • Eine Geschäftsprozess-Engine, die auf ein Ereignis "Ich bin fertig" wartet. Diese Engine implementiert die Anwendungsfälle und den Fluss. 
  • Ein Orchestrierungs-Mikrodienst, sagen wir, der Auftragsbearbeitungsdienst selbst, der den Fluss/die Anwendungsfälle Ihrer Domäne kennt
  • Alles andere, woran ich noch nicht gedacht habe

Der Hauptpunkt dabei ist, dass die Steuerung extern ist. Dies liegt daran, dass alle Ihre Anwendungskomponenten aus einzelnen Bausteinen bestehen, die lose miteinander verbunden sind. Wenn sich Ihre Anwendungsfälle ändern, müssen Sie eine Komponente an einer Stelle ändern, die Orchestrierungskomponente. Wenn Sie einen anderen Auftragsfluss hinzufügen, können Sie problemlos einen anderen Orchestrator hinzufügen, der den ersten nicht beeinträchtigt. Beim Micro-Service-Denken geht es nicht nur um Skalierbarkeit und Phantasie REST APIs, sondern auch um eine klare Struktur, reduzierte Abhängigkeiten zwischen Komponenten und die Wiederverwendung gängiger Daten und Funktionen, die in Ihrem Unternehmen gemeinsam genutzt werden.

HTH, Mark

4
mp911de

Wenn der State verwaltet werden muss, ist das Event Sourcing mit CQRS die ideale Kommunikationsmöglichkeit. Ansonsten kann ein Asynchronous Messaging System (AMQP) für die Kommunikation zwischen Mikroservices verwendet werden.

Aus Ihrer Frage ist klar, dass die ES mit CQRS die richtige Mischung sein sollte. Wenn Sie Java verwenden, werfen Sie einen Blick auf das Axon-Framework. Oder erstellen Sie eine benutzerdefinierte Lösung mit Kafka oder RabbitMQ.

1
Rajeesh Koroth

die Antwort auf die ursprüngliche Frage lautet SAGA-Muster.

0
Harold Vera