it-swarm.com.de

Datenaustausch zwischen Mikrodiensten

Aktuelle Architektur:

enter image description here

Problem:

Wir haben einen zweistufigen Ablauf zwischen Frontend- und Backend-Ebenen.

  • Erster Schritt: Das Frontend validiert eine Eingabe I1 vom Benutzer auf Microservice 1 (MS1)
  • Zweiter Schritt: Das Frontend übermittelt I1 und weitere Informationen an den Microservice 2

Der Mikrodienst 2 (MS2) muss die Integrität von I1 validieren, da er vom Frontend kommt. Wie vermeide ich eine neue Abfrage an MS1? Was ist der beste Ansatz?

Flows, die ich zu optimieren versuche, die Schritte 1.3 und 2.3 zu entfernen

Fluss 1:

  • 1.1 Der Benutzer X fordert Daten (MS2_Data) von MS2 an
  • 1.2 Der Benutzer X speichert Daten (MS2_Data + MS1_Data) auf MS1
  • 1.3 Das MS1 überprüft die Integrität von MS2_Data mithilfe einer B2B-HTTP-Anforderung
  • 1.4 Der MS1 verwendet MS2_Data und MS1_Data, um die Datenbank 1 beizubehalten und die HTTP-Antwort zu erstellen.

Fluss 2:

  • 2.1 Auf dem Benutzer X sind bereits Daten (MS2_Data) im lokalen/Sitzungsspeicher gespeichert
  • 2.2 Der Benutzer X speichert Daten (MS2_Data + MS1_Data) auf MS1
  • 2.3 Das MS1 überprüft die Integrität von MS2_Data mithilfe einer B2B-HTTP-Anforderung
  • 2.4 Der MS1 verwendet MS2_Data und MS1_Data, um die Datenbank 1 beizubehalten und die HTTP-Antwort zu erstellen.

Ansatz

Ein möglicher Ansatz besteht darin, eine B2B-HTTP-Anforderung zwischen MS2 und MS1 zu verwenden, aber wir würden die Validierung im ersten Schritt duplizieren. Ein anderer Ansatz ist das Duplizieren von Daten von MS1 ​​nach MS2. Dies ist jedoch aufgrund der Datenmenge und der Volatilität untragbar. Vervielfältigung scheint keine praktikable Option zu sein.

Eine geeignetere Lösung ist meiner Meinung nach das Frontend, das dafür verantwortlich ist, alle vom Mikrodienst 1 benötigten Informationen über den Mikrodienst 2 abzurufen und an den Mikrodienst 2 zu liefern. Dadurch werden alle diese B2B-HTTP-Anforderungen vermieden.

Das Problem ist, wie der Mikrodienst 1 den vom Frontend gesendeten Informationen vertrauen kann. Vielleicht kann die Nachricht mit JWT , um die Daten vom Mikrodienst 1 und vom Mikrodienst 2 zu signieren, überprüft werden.

Hinweis Jedes Mal, wenn der Mikrodienst 2 Informationen vom Mikrodienst 1 benötigt, wird eine B2B-http-Anforderung ausgeführt. (Die HTTP-Anforderung verwendet ETAG und Cache Control: max-age ). Wie vermeide ich das?

Architekturziel

enter image description here

Der Mikrodienst 1 benötigt die Daten des Mikrodienstes 2 bei Bedarf, um die Daten von MS1_Data und MS2_Data in der MS1-Datenbank beizubehalten, sodass der ASYNC-Ansatz mit einem Broker hier nicht angewendet wird.

Meine Frage ist, ob es ein Entwurfsmuster, eine bewährte Methode oder einen Rahmen gibt, um diese Art von Schubkommunikation zu ermöglichen.

Der Nachteil der aktuellen Architektur ist die Anzahl der B2B-HTTP-Anforderungen, die zwischen den einzelnen Mikrodiensten ausgeführt werden. Selbst wenn ich einen Cachesteuerungsmechanismus verwende, wird die Antwortzeit jedes Mikrodienstes beeinträchtigt. Die Reaktionszeit der einzelnen Mikrodienste ist kritisch. Ziel ist es, eine bessere Leistung zu erzielen und das Frontend als Gateway für die Verteilung von Daten über mehrere Mikrodienste zu verwenden, wobei jedoch eine Schubkommunikation verwendet wird .

MS2_Data ist nur eine Entitäts-SID wie die Produkt-SID oder die Hersteller-SID, die das MS1 verwenden muss, um die Datenintegrität zu gewährleisten.

Mögliche Lösung

enter image description here

Die Idee ist, das Gateway als API-Gateway-Anforderungsverarbeitung zu verwenden, bei der einige HTTP-Antworten von MS1 ​​und MS2 zwischengespeichert und als Antwort auf MS2 SDK und MS1 SDK verwendet werden. Auf diese Weise wird keine Kommunikation (SYNC OR ASYNC)) direkt zwischen MS1 ​​und MS2 hergestellt, und es wird auch eine Duplizierung von Daten vermieden.

Natürlich ist die oben genannte Lösung nur für gemeinsame UUID/GUID über Mikrodienste. Für vollständige Daten wird ein Ereignisbus verwendet, um Ereignisse und Daten auf asynchrone Weise über Mikrodienste zu verteilen (Ereignisbeschaffungsmuster).

Inspiration: https://aws.Amazon.com/api-gateway/ und https://getkong.org/

Verwandte Fragen und Dokumentation:

29
Leonel

Überprüfen Sie den Abschnitt Mögliche Lösung auf meine Frage:

Die Idee ist, das Gateway als API-Gateway-Anforderungsverarbeitung zu verwenden, bei der einige HTTP-Antworten von MS1 ​​und MS2 zwischengespeichert und als Antwort auf MS2 SDK und MS1 SDK verwendet werden. Auf diese Weise wird keine Kommunikation (SYNC OR ASYNC)) direkt zwischen MS1 ​​und MS2 hergestellt, und es wird auch eine Duplizierung von Daten vermieden.

Inspiration: https://aws.Amazon.com/api-gateway/ und https://getkong.org/

2
Leonel

Aus den Fragen und Kommentaren geht hervor, dass Sie versuchen, die Blöcke neu anzuordnen, um die Leistung des Systems zu verbessern. Wie in den Diagrammen beschrieben, schlagen Sie vor, dass das Gateway anstelle von microservice1 microservice2 abfragt und dann microservice1 mit den Informationen von microservice2 abfragt.

Als solches sehe ich nicht, wie dies die Systemleistung signifikant erhöhen würde, sondern die Änderung scheint nur die Logik zu verschieben.

Um Abhilfe zu schaffen, sollte die Leistung des kritischen Mikroservices2 verbessert werden. Dies kann durch Profilerstellung und Optimierung der microservice2-Software (vertikale Skalierung) erfolgen, und/oder Sie können den Lastenausgleich (horizontale Skalierung) einführen und microservice2 auf mehreren Servern ausführen. Das in diesem Fall zu verwendende Entwurfsmuster ist Dienstlastausgleichsmuster .

2
iluwatar

Sie können erwägen, Ihre Synchronisierungsmethode für die B2B-Kommunikation mithilfe des Publish-Subscribe-Musters auf die asynchrone zu ändern. In dieser Situation ist der Service-Betrieb unabhängiger und Sie müssen möglicherweise nicht immer B2B-Anforderungen ausführen.

Die Art und Weise, wie Sie es in verteilten Systemen schneller machen, ist die Denormalisierung. Wenn sich ms2data selten ändert, z. Wenn Sie es mehr lesen als umschreiben, müssen Sie es dienstübergreifend duplizieren. Auf diese Weise reduzieren Sie die Latenz und die zeitliche Kopplung. Der Kopplungsaspekt kann in vielen Situationen sogar wichtiger sein als die Geschwindigkeit.

Wenn ms2data eine Produktinformation ist, sollte ms2 das ProductCreated-Ereignis, das ms2data enthält, auf einem Bus veröffentlichen. Ms1 sollte dieses Ereignis abonniert haben und ms2data in seiner eigenen Datenbank speichern. Wenn ms1 jetzt ms2data benötigt, wird es nur lokal gelesen, ohne dass Anforderungen an ms2 ausgeführt werden müssen. Das bedeutet zeitliche Entkopplung. Wenn Sie diesem Muster folgen, wird Ihre Lösung fehlertoleranter und das Herunterfahren von ms2 beeinflusst ms1 in keiner Weise.

Lesen Sie eine gute Artikelserie , die die Probleme der Synchronisierungskommunikation in der Microservices-Architektur beschreibt.

Verwandte SO Fragen hier und hier Erörtern Sie ähnliche Probleme, und werfen Sie einen Blick darauf.

1
IlliakaillI

Es ist jedoch schwierig, die Realisierbarkeit einer Lösung zu beurteilen, ohne "in die Kisten" zu schauen:

  • Wenn Sie sich hier nur darum kümmern, dass das Frontend die Daten nicht manipuliert, können Sie eine Art "Signatur" des von MS2 an das Frontend gesendeten Datenpakets erstellen und die Signatur zusammen mit dem Paket an MS1 ​​weitergeben. Die Signatur kann ein Hash des Pakets sein, das mit einer Pseudozufallszahl verkettet ist, die auf deterministische Weise aus einem von den Mikrodiensten gemeinsam genutzten Startwert generiert wurde (sodass MS1 dieselbe Pseudozufallszahl wie MS2 neu erstellen kann, ohne dass eine zusätzliche B2B-HTTP-Anforderung erforderlich ist, und anschließend überprüft werden muss die Integrität des Pakets).

  • Die erste Idee, die mir einfällt, ist zu prüfen, ob der Besitz der Daten geändert werden kann. Wenn MS1 ​​häufig auf eine Teilmenge von Daten von MS2 zugreifen muss, kann möglicherweise der Besitz dieser Teilmenge von MS2 auf MS1 verschoben werden.

  • In einer idealen Welt sollten die Mikrodienste vollständig eigenständig sein, jeder mit einer eigenen Persistenzschicht und einem vorhandenen Replikationssystem. Sie sagen, dass ein Broker keine praktikable Lösung ist. Wie steht es also mit einer gemeinsam genutzten Datenschicht?

Ich hoffe es hilft!

1
lud1977