Sollten Microservices miteinander sprechen?

30

Ich entwerfe eine Anwendung unter Verwendung von Micro-Services und bin mir nicht sicher, welchen Mechanismus ich am besten verwenden kann, um Daten von mehreren Services zu sammeln.

Ich glaube, es gibt zwei Möglichkeiten:

  • Integrieren Sie einen Kommunikationsmechanismus zwischen den Diensten, mit dem die Dienste direkt kommunizieren können. Das API-Gateway ruft einen einzelnen Dienst auf, der dann andere Dienste aufruft, um Daten zu erfassen, bevor die konsolidierte Antwort an das API-Gateway zurückgegeben wird. Die API gibt dann die Antwort an den Aufrufer zurück. (Dies müssten synchrone Anrufe sein, wenn der Aufruf von serviceB die Antwort von serviceA erfordert. IE Seperate Person and Address Services.)
  • Lassen Sie das API-Gateway jeden Dienst direkt aufrufen und die Daten in der API konsolidieren, bevor Sie die Antwort zurückgeben.

Ich neige zur zweiten Option, da ein Gespräch zwischen den Diensten zu einer Kopplung führen würde. In diesem Fall könnte ich auch nur eine monolithische Anwendung entwerfen. Es gibt jedoch ein paar schwerwiegende Nachteile, die ich mit dieser Option auf den Kopf stellen kann:

  • Wenn die API mehrere Aufrufe an mehrere Dienste ausführt, erhöht sich die Belastung des API-Servers, insbesondere wenn einige dieser Aufrufe blockiert werden.

  • Diese Methode bedeutet, dass die API wissen muss, was die Anwendung versucht (IE Logic müsste in die API programmiert werden, um die Dienste der Reihe nach aufzurufen und dann die Daten zu konsolidieren), und nicht nur fungieren als dummer "Endpunkt" für die Mikrodienste.

Ich würde gerne wissen, wie die Standardlösung für dieses Problem aussieht und ob mir noch eine dritte Option fehlt.

KidCode
quelle
Können Sie einen Kontext angeben? Was ist Ihre App und was versucht sie zu tun
Ewan
Meine Vermutung liegt irgendwo zwischen Ihren beiden Möglichkeiten: Jeder Mikrodienst kommuniziert mit anderen Mikrodiensten nach Bedarf, um seine Arbeit zu erledigen. Das API-Gateway kann auch als Mikrodienst betrachtet werden, bei dem die Arbeit in erster Linie an andere Dienste delegiert wird.
Bart van Ingen Schenau
Ich würde argumentieren, dass das Komponieren von Microservices auf der Serverseite den Hauptzweck von Microservices zunichte macht. Die ganze Idee ist, Services unabhängig zu machen und die Orchestrierung dem Client zu überlassen. Aber vielleicht bin ich unpraktisch
Sridhar Sarnobat

Antworten:

21

Ich würde generell davon abraten, Mikrodienste synchron miteinander kommunizieren zu lassen. Das große Problem ist die Kopplung. Das bedeutet, dass die Dienste jetzt miteinander gekoppelt sind. Wenn einer von ihnen ausfällt, ist der zweite jetzt ganz oder teilweise funktionsunfähig.

Ich würde klar zwischen Zustandsänderungsoperationen und Leseoperationen (CQS Command Query Separation) unterscheiden ) unterscheiden. Für Zustandsänderungsoperationen würde ich irgendeine Art von Nachrichteninfrastruktur verwenden und Feuer fangen und vergessen. Bei Abfragen würden Sie die synchrone Anforderungs-Antwort-Kommunikation verwenden und könnten eine http-API verwenden oder direkt zu Ihrem Datenspeicher gehen.

Wenn Sie Messaging verwenden, können Sie auch unter Publish Subscribe nachsehen, um Ereignisse zwischen Diensten auszulösen.

Ein weiterer zu berücksichtigender Punkt ist die (transaktionale) Datenfreigabe (im Gegensatz zu schreibgeschützten Ansichten). Wenn Sie Ihren internen Status offenlegen, kann der Leser möglicherweise den falschen Status Ihrer Daten oder die falsche Version erhalten und Ihre Daten möglicherweise auch sperren.

Versuchen Sie zu guter Letzt, alles in Ihrer Macht Stehende zu tun, um Ihre Dienste autonom zu halten (zumindest auf logischer Ebene).

Hoffe das macht Sinn.

Sean Farmar
quelle
11

Es hängt davon ab, warum Sie diese Daten benötigen. Wenn es für die Benutzeroberfläche ist, dann ist es vollkommen in Ordnung. Außerdem ist es so, wie es sein sollte. Chris Richardson hat eine nette Erklärung für dieses Konzept und Sam Newman hat einen großartigen Artikel über ein sehr ähnliches Konzept namens Backends for Frontends .

Aber wenn Sie es für eine Logik benötigen, ist die Wahrscheinlichkeit groß, dass Ihre Servicegrenzen falsch sind.

Der gesunde Menschenverstand sagt uns, dass unsere Dienstleistungen mehrere Eigenschaften haben sollten . Sie sind:

  1. Geringe Kopplung. Wenn Sie in Service A einige Änderungen vornehmen, möchten Sie nicht, dass sich diese auf Service B auswirken.
  2. Hoher Zusammenhalt. Wenn Sie eine Funktion implementieren müssen, soll die geringstmögliche Anzahl von Diensten betroffen sein.
  3. Hohe Autonomie. Wenn ein Dienst ausfällt, soll nicht das gesamte System ausgefallen sein.
  4. Korrekte Granularität. Sie möchten nicht, dass Ihre Dienste zu gesprächig sind, da Ihr Netzwerk komplexer ist, als Sie vielleicht denken.
  5. Dienste sollten über Ereignisse kommunizieren. Sie möchten nicht, dass sich Ihr Service gegenseitig bewusst ist, da dies die Wartbarkeit verringert. Überlegen Sie, was passiert, wenn Sie einen neuen Dienst hinzufügen müssen.
  6. Dezentrale Daten. Ein Dienst sollte die Art und Weise, in der Informationen gespeichert werden, nicht freigeben. Genau wie ein gutes Objekt enthüllt es Verhalten, keine Daten.
  7. Service-Choreografie über Orchestrierung.

Um dies zu erreichen, behandeln Sie Ihre Servicegrenzen als geschäftliche Funktionen . Ein formaler Prozess zum Identifizieren von Dienstgrenzen sieht wie folgt aus:

  1. Identifizieren Sie übergeordnete Grenzen. Ich stelle sie mir gerne als Schritte vor, die Ihre Organisation durchführen sollte, um ihr Geschäftsziel zu erreichen und ihren Geschäftswert zu erreichen. Sie können die Idee grundlegender Schritte durch einen Blick auf die Wertschöpfungskette von Porter gewinnen .
  2. Tauchen Sie in jedem Service tiefer ein. Identifizieren Sie in sich geschlossene Kindereinheiten mit ihren eigenen Verantwortlichkeiten.
  3. Achten Sie auf die Art und Weise, wie sie kommunizieren. Richtige Dienste kommunizieren hauptsächlich über Ereignisse. Denken Sie an Ihre Organisationsstruktur. Die Kommunikation in ihnen ist ziemlich intensiv, obwohl in der Regel einige externe Ereignisse ausgesetzt sind.

Ein Beispiel für die Anwendung dieses Ansatzes könnte von Interesse sein.

Zapadlo
quelle
1

Ich würde mich auch standardmäßig dem zweiten Ansatz zuwenden, obwohl dies möglicherweise nicht in Ihrem "API-Gateway" der Fall ist, aber ich würde es für völlig vernünftig halten, einen neuen Mikrodienst zu erstellen, dessen einziger Zweck darin besteht, Anforderungen an andere Mikrodienste zu orchestrieren und zu repräsentieren die Daten in einer übergeordneten Form. In einer Mikrodienstarchitektur würde ich mich dagegen lehnen, dass die "Basis" -Mikrodienste direkt miteinander kommunizieren.

Um dies ein bisschen weniger subjektiv zu machen, nehmen wir an, ein Dienst hängt von einem anderen ab, wenn der erste direkt oder indirekt Daten oder Dienste vom zweiten benötigt . In mathematischen Begriffen wollen wir, dass diese Beziehung eine Teilordnung und keine Vorordnung ist . Wenn Sie Ihr Abhängigkeitsdiagramm in Diagrammform gezeichnet haben, sollten Sie ein Hasse-Diagramm erhaltenund keine (gerichteten) Zyklen haben. (In einem Hasse-Diagramm sind die Kanten implizit von unten nach oben gerichtet.) Als weitere Richtlinie möchten Sie, dass die Pfade von oben nach unten im Allgemeinen kürzer sind. Dies bedeutet, dass Sie standardmäßig direkter von den Dingen abhängen möchten. Die Gründe dafür sind, dass die Anzahl der Probleme, die bei einer bestimmten Anforderung auftreten können, minimiert wird, der Overhead minimiert wird und die Komplexität verringert wird. Im "idealen" Fall nach dieser Metrik hätte das Hasse-Diagramm also nur zwei Ebenen. Natürlich gibt es viele Gründe, warum Sie Zwischendienste wie Caching, Konsolidierung, Lastenausgleich und Fehlermanagement einführen möchten.

Um auf Ihr zweites Anliegen einzugehen, dass das API-Gateway "intelligent" ist, müssen Sie bei einem Muster, das derzeit mit Frameworks wie Falcor und Relay / GraphQL an Bedeutung gewinnt, präzisieren , was zu tun ist, damit das "API-Gateway" generisch kann Führen Sie diese Spezifikationen aus, ohne zu wissen, worauf es GetTimelineankommt. Stattdessen wird eine Anfrage wie "Diese Benutzerinformationen vom Benutzerdienst anfordern und diese Posts vom Postdienst abrufen" oder was auch immer gesendet.

Derek Elkins
quelle
0

Ich vermute, dass Ihr Bedarf an Diensten, die sich gegenseitig "anrufen", darauf hindeutet, dass Sie mit einem System fortfahren, das nicht über eine gute Architektur verfügt, da dieses Erfordernis, dass Microservices sich gegenseitig "anrufen", eine Form der Kopplung ist, die selten auftritt, wenn Microservices sind entsprechend ausgelegt.

Können Sie mehr über das Problem erklären, das Sie lösen möchten? In einfachem Englisch?

Ben
quelle