Sollten Dienste in einer Microservice-Architektur direkt miteinander kommunizieren?

10

Ich habe eine Reihe von Webdiensten, die eine Webanwendung bilden. Clients können über REST-API-Aufrufe auf diese Services zugreifen.

Sollten diese Dienste in der Lage sein, direkt miteinander zu sprechen? Wenn ja, würde das sie nicht zum Paar machen, was gegen das Konzept der Microservices verstößt?

Sollte der Client sie direkt nacheinander anrufen, um die Daten zu erhalten, die zum Laden einer Webseite auf dem Client erforderlich sind?

Oder sollte ich zusätzlich zu meinen Diensten eine weitere Ebene haben, die eine Anforderung vom Client verarbeitet, die Daten für diese Anforderung abruft und sie dann an den Client zurücksendet?

cod3min3
quelle
Wenn die Dinge völlig entkoppelt sind, handelt es sich um völlig separate Produkte. Der Benutzer müsste sich also bei Contoso anmelden, dann würde Contoso Login sagen "Sie sind jetzt angemeldet!" ... und dann gehen sie zu Contoso Sensitive Data Storage. Aktivieren Sie das Kontrollkästchen "Ja, ich bin angemeldet" "... dann kopieren Sie die Daten von diesem in Contoso Data Processor ...
user253751

Antworten:

15

Wenn Sie möchten, dass Ihre Dienste auf diesem Bild aussehen, dann ja: Geben Sie hier die Bildbeschreibung ein Es ist nicht so, dass Sie es nicht können, aber meistens hat es schlimme Konsequenzen. Die Kommunikation über REST entkoppelt Ihre Dienste nicht wesentlich. Wenn sich einige Dienstschnittstellen ändern, müssen höchstwahrscheinlich alle abhängigen Dienste geändert und erneut bereitgestellt werden. Während der erneuten Bereitstellung von Diensten müssen Sie alle abhängigen Dienste ablegen, was für Hochverfügbarkeitsstandards nicht als gutes Design angesehen wird.

Am Ende haben Sie eine Microservices-Anwendung, die langsamer ist als eine alternative Monolith-App, aber fast alle die gleichen Probleme hat!

Ich muss @Robert Harvey nicht zustimmen

In der Praxis kommunizieren jedoch einer oder mehrere Ihrer Microservices (möglicherweise alle) mit einem zentralen Datenspeicher wie einer SQL-Datenbank.

Die Integrationsdatenbank ist ein bekanntes Antipattern

Eine viel bessere Lösung besteht darin, das Publish-Subscribe-Muster zu verwenden, um die Kommunikation zwischen Ihren Diensten asynchron zu gestalten:

Geben Sie hier die Bildbeschreibung ein

Bitte werfen Sie einen Blick auf die Art und Weise, wie CQRS / ES diese Kommunikationsmethode implementiert. Greg Young und andere bieten unzählige nette Videos zu diesem Thema an. Google einfach nach dem Schlüsselwort "CQRS / ES". Bei diesem Ansatz wird jeder Dienst gleichzeitig Herausgeber und Abonnent, wodurch die Dienste viel weniger gekoppelt werden können.

Hier ist eine gute Reihe von Artikeln über Microservices , die die Kontroverse um das Thema beleuchten. Sehr ausführliche Erklärung mit schönen Abbildungen.

IlliakaillI
quelle
2
Zunächst einmal habe ich den Begriff "Integrationsdatenbank" nur von Fowler gehört. Nimm etwas nicht als Evangelium, nur weil es einer gesagt hat. Zweitens haben Sie nicht genügend Informationen, um eine von mir beschriebene "Integrationsdatenbank" aufzurufen. Drittens nennt Fowler solche Datenbanken im selben Artikel, den Sie verlinkt haben, tatsächlich unter den richtigen Umständen nützlich. Ich mag die Idee eines Ereignisbusses, obwohl ich nicht sehe, wie sich das vom Aufrufen der üblichen API des Microservice unterscheidet, es sei denn, Sie können die Effizienz steigern.
Robert Harvey
Vielen Dank, Robert, ich habe Fowlers Artikel verlinkt, um die Idee besser zu veranschaulichen und nicht um von der Autorität zu streiten. Die Art und Weise, wie Sie diesen Ansatz beschrieben haben, klingt sehr nach einer Integrationsdatenbank. Wenn es anders ist, ist das überhaupt nicht offensichtlich. In Bezug auf die richtigen Umstände - Ich denke, dass die Integration von Microservices über eine Datenbank keine gute Idee ist, da sie uns zu einer monolithischen Architektur zurückdrängt.
IlliakaillI
1
Sicher: Jeder Mikrodienst kommuniziert mit seiner eigenen Datenbank oder mit den Tabellen in derselben Datenbank, die sich nicht auf Tabellen anderer Dienste beziehen. Auf diese Weise tauschen Dienste niemals Informationen über die Datenbank aus, was bedeutet, dass Sie leicht horizontal skalieren können und es viel weniger Engpässe gibt. Und weil sie nicht dieselben Tabellen verwenden, wirken sich Änderungen in einem Teil der App weniger wahrscheinlich auf andere Teile aus.
IlliakaillI
1
Sie können das nicht kategorisch als absolut bezeichnen. Möglicherweise gibt es zwei Dienste, die dieselben Informationen in derselben Datenbank benötigen. Sie benötigen sie nur gelegentlich. Es gibt kein Skalierungsproblem, um auf diese Weise darauf zuzugreifen. Die beiden Dienste greifen ohnehin bereits für andere Zwecke auf die Datenbank zu oder API-Endpunkt, nur um dies zu erreichen, wäre lächerlich.
Robert Harvey
1
Um jedoch einen geschäftlichen Nutzen zu erzielen, möchten Sie Daten kombinieren - "Zeigen Sie mir alle Abwassersysteme mit unzureichender Speicherkapazität angesichts der folgenden Radardaten des einfallenden Regens und färben Sie diese Karte der Gemeinden anhand des Ergebnisses". Wenn Sie alle Ihre Daten in Dienste aufteilen, bedeutet dies nur, dass Sie die Daten erst später kombinieren können. Wenn Sie den Diensten verbieten, miteinander zu kommunizieren, zwingen Sie sich einfach dazu, alle Daten auf einen Client zu verschieben und die Daten dort zu verbinden. Sie möchten Daten irgendwo koppeln, da dies letztendlich einen Anwendungswert ergibt.
RemcoGerlich
8

Wenn Sie lesen, was Udi Dahan über SOA zu sagen hat, erhalten Sie viele sehr gute Ideen .

Ein Service ist die technische Autorität für eine bestimmte Geschäftsfähigkeit. Alle Daten oder Regeln dürfen nur einem Dienst gehören.

Dies bedeutet, dass wir selbst dann, wenn Dienste die Ereignisse des anderen veröffentlichen und abonnieren, immer wissen, was die maßgebliche Quelle der Wahrheit für jedes Datenelement und jede Regel ist.

Wenn wir Services aus der Sicht der Geschäftsfunktionen betrachten, sehen wir, dass viele Benutzeroberflächen Informationen zu verschiedenen Funktionen enthalten - den Preis eines Produkts sowie die Frage, ob es auf Lager ist oder nicht. Damit wir die obige Definition von Diensten einhalten können, verstehen wir, dass solche Benutzeroberflächen tatsächlich ein Mashup sind - wobei jeder Dienst das Fragment der Benutzeroberfläche aufweist, das sich mit seinen bestimmten Daten befasst.

Insbesondere in Bezug auf die UI-Komposition ist der Artikel von Mauro Servienti über die UI-Komposition ein guter Ausgangspunkt. Siehe auch Udis Video, das hier verfügbar ist .

Sollten diese Dienste in der Lage sein, direkt miteinander zu sprechen? Wenn ja, würde das sie nicht zum Paar machen, was gegen das Konzept der Microservices verstößt?

Wenn zwei Dienste Nachrichten miteinander austauschen, erhalten Sie eine Kopplung. Die primäre Antwort lautet, dass sie an die API des anderen Dienstes gekoppelt sind - den Vertrag, den der Dienst verspricht, auch dann stabil zu bleiben, wenn sich seine Interna ändern.

Darüber hinaus können Techniken wie die Serviceerkennung die Abhängigkeit von einem bestimmten Dienstanbieter verringern, und Nachrichtenbroker können die Produzenten und Verbraucher entkoppeln (sie müssen die Nachrichten der anderen noch verstehen und wissen, wie sie mit der API des Nachrichtenbrokers interagieren können - es gibt keine Magie ).

VoiceOfUnreason
quelle
7

Es kommt darauf an, was Sie unter "direkt" verstehen.

Gemäß der Microservices-Architektur ist es vollkommen in Ordnung, Microservices zu haben, die andere Microservices entweder auf Ihrem eigenen Server oder sogar auf externen Servern über eine Schnittstelle wie REST aufrufen.

Was nicht in Ordnung ist, ist, dass ein Microservice einen anderen mithilfe direkter Methodenaufrufe aufruft. das würde beide Mikrodienste zu einem Teil desselben Monolithen machen.

Mike Nakis
quelle
es ist nicht in Ordnung und wird schlimme Folgen haben. Siehe meine Antwort für weitere Details.
IlliakaillI
@IlliakaillIch sage, dass es "gemäß der Microservices-Architektur" in Ordnung ist. Ich behaupte nicht, dass die Microservices-Architektur frei von Konsequenzen ist oder dass keine Verbesserungen daran vorgenommen werden können. Die Frage hier ist "ist X nach dem Buch oder nicht?" und die richtige Antwort ist, dass es bei korrekter Definition von X nach dem Buch geht.
Mike Nakis
Gibt es ein "Nachschlagewerk", in dem Sie erfahren, wie Sie eine echte "Microservices-Architektur" erstellen? Microservices werden heutzutage zu einem Schlagwort und viele Leute haben Bücher darüber geschrieben, wie man Monolithen auf REST baut. Schauen Sie sich nur das erste Diagramm in meiner Antwort an. Es ist nicht sinnvoll, ein System auf diese Weise aufzubauen. Wenn Sie es aus irgendeinem seltsamen Grund tun, machen Sie es definitiv falsch. Du gehst besser stattdessen mit Monolith. Wenn Sie Ihre Designentscheidungen unterstützen, indem Sie blind auf einige Bücher verweisen (ein Argument der Autorität vorbringen), ist dies kein richtiger Ansatz für das Software-Design.
IlliakaillI
5

Sollten diese Dienste in der Lage sein, direkt miteinander zu sprechen? Wenn ja, würde das sie nicht zum Paar machen, was gegen das Konzept der Microservices verstößt?

Kopplung ist kein schlechtes Wort. Jede Anwendung hat bereits einen gewissen Kopplungsgrad; Die Anwendungen, die mit Ihren Microservices kommunizieren, sind bereits mit den Microservices gekoppelt , da sie sonst nicht funktionieren würden.

Was Sie bei Microservices wirklich suchen, ist eine lose Kopplung . Sie können dies erreichen, indem Sie einfach einen Mikroservice den anderen über seine öffentliche API abfragen lassen oder einen Ereignisbus verwenden.

In der Praxis kommunizieren jedoch einer oder mehrere Ihrer Microservices (möglicherweise alle) mit einem zentralen Datenspeicher wie einer SQL-Datenbank. Abhängig davon, wie Sie Ihr Ziel erreichen möchten, kann es sein, dass ein Mikrodienst die Datenbankdaten auf irgendeine Weise ändert, die der andere Mikrodienst abfragt, um die Änderung zu übernehmen.

Robert Harvey
quelle
3
"Integrationsdatenbank" ist ein bekanntes Antipattern. Weitere Informationen finden Sie in meiner Antwort.
IlliakaillI
2

Es scheint, dass Menschen, wenn sie über SOAs und Architektur im Allgemeinen sprechen, in Semantik und Jargon verwickelt sind. Was macht einen Service "Mikro"? Letztendlich handelt es sich um eine Reihe von Merkmalen, die in dem von Ihnen verwendeten "Bewertungssystem" den Dienst eindeutig nicht "nicht mikro" machen. Was sagte der Oberste Gerichtshof über Unanständigkeit? "Ich werde es wissen, wenn ich es sehe."

Ich bin sicher, einige Leute werden sagen, dass dies keine Antwort ist, aber dann verpassen sie den Punkt. Mikrodienstarchitekturen sollen verschiedene Probleme vermeiden, darunter das Problem der "engen Kopplung". Wenn Sie also am Ende ein Gewirr von Mikrodiensten erstellen, die von zu vielen feinen Details voneinander abhängen, haben Sie eine enge Kopplung erstellt, die - unabhängig davon, ob Sie einen Pub / Sub-Nachrichtenbus oder direkte Anrufe verwenden - zerstört Ihre Fähigkeit, aus den Teilen neue Lösungen zu erstellen, einzelne Teile neu zu konfigurieren, ohne das gesamte System herunterzufahren usw.

Flackernder Punkt com
quelle
1

Sollte der Client sie direkt nacheinander anrufen, um die Daten zu erhalten, die zum Laden einer Webseite auf dem Client erforderlich sind?

Es hängt davon ab, ob; Ich würde jedoch vorschlagen, dem Client direkt nutzbare Funktionen bereitzustellen und die Details der Zusammenstellung der Ergebnisse zu verbergen (zu kapseln) (z. B. über mehrere Mikrodienste).

Wenn beim Kombinieren einzelner Mikrodienstergebnisse durch den Client zu viel Logik erforderlich ist, kann dies dazu führen, dass sich versehentlich eine Geschäftslogik in den Client einschleicht. Es kann auch mehr von Ihrer internen Architektur für den Client verfügbar machen, als Sie möchten, was ein späteres Refactoring der Microservices behindert.

Das heißt, bei Microservices ist es manchmal hilfreich, einen Wrapper-Microservice zu haben, der dem Client einen Endpunkt mit nützlichen Abstraktionen bietet und eine höhere Koordination anderer (möglicherweise jetzt interner) Microservices durchführt.


(Außerdem sind Hin- und Rückflüge zum Kunden wahrscheinlich teurer als von Ihren Microservices zueinander.)


Wenn Sie sich beispielsweise die Richtung ansehen, in die GraphQL geht, finden Sie Clients, die direkt relevante Abfragen an einen Endpunkt senden, der möglicherweise als Sammlung von Mikrodiensten implementiert ist oder nicht. Da die Architektur der Microservices hinter GraphQL verborgen ist, ist die Architektur einfacher umzugestalten und für den Client auch benutzerfreundlicher. Siehe zum Beispiel /programming//a/38079681/471129 .

Erik Eidt
quelle
1

Der Hauptzweck von Mikrodiensten besteht darin, Ihre Anwendung lose zu koppeln. Daher können sich Dienste nicht gegenseitig anrufen. Andernfalls wird es gebunden gekoppelt. Aber was machen wir, wenn wir zwei Dienste haben, die Daten gemeinsam nutzen müssen? Die Antwort lautet Message Broker. Damit der Dienst, der Daten vom Client erhält, die Daten an den zentralen Nachrichtenbroker weitergeben kann, müssen die Dienste diese Daten verwenden, um sie zu verbrauchen, zu transformieren und in seinen eigenen Datenspeicher zu stellen. Ich empfehle Kafka, da Sie mit Kafka Stream Daten aus verschiedenen Themenbereichen im Handumdrehen verknüpfen können. PS. Besser, Sie trennen Ihre Mikrodienste nach Funktionen.

Panuwat Anawatmongkhon
quelle