Ich finde es schwierig, Datenvervielfältigungen oder eine gemeinsam genutzte Datenbank selbst für das einfachste Mikrodienstdesign zu vermeiden, was mich glauben lässt, dass mir etwas fehlt. Hier ist ein grundlegendes Beispiel für das Problem, mit dem ich konfrontiert bin. Angenommen, jemand verwendet eine Webanwendung, um ein Inventar zu verwalten, dann würde er zwei Dienste benötigen. eine für das Inventar, das die Artikel und die Menge auf Lager verwaltet, und einen Benutzerservice, der die Benutzerdaten verwaltet. Wenn wir prüfen möchten, wer die Datenbank auf Lager hat, können wir der Datenbank die Benutzer-ID für den Inventarservice als Wert für den letzten Bestand hinzufügen.
Unter Verwendung der Anwendung möchten wir möglicherweise alle Artikel anzeigen, die zur Neige gehen, und eine Liste, von wem sie das letzte Mal eingelagert wurden, damit wir sie auffordern können, sie erneut aufzufüllen. Unter Verwendung der oben beschriebenen Architektur würde eine Anfrage an den Inventarservice gestellt, um die Artikeldetails aller Artikel abzurufen, bei denen die Menge kleiner als 5 ist. Dies würde eine Liste mit den Benutzer-IDs zurückgeben. Anschließend wird eine separate Anfrage an den Benutzerservice gesendet, um den Benutzernamen und die Kontaktdaten für die Liste der Benutzer-IDs abzurufen, die vom Inventarservice bezogen wurden.
Dies scheint schrecklich ineffizient zu sein, und es werden nicht mehr viele Dienste benötigt, bevor mehrere Anforderungen an verschiedene Dienst-APIs gesendet werden, die wiederum mehrere Datenbankabfragen durchführen. Eine Alternative besteht darin, die Benutzerdetails in den Inventardaten zu replizieren. Wenn ein Benutzer seine Kontaktdaten ändert, müssen wir die Änderung über alle anderen Dienste replizieren. Dies scheint jedoch nicht mit der begrenzten Kontextidee von Mikrodienstleistungen übereinzustimmen. Wir könnten auch eine einzige Datenbank verwenden und diese zwischen verschiedenen Diensten teilen und alle Probleme einer Integrationsdatenbank haben .
Was ist der richtige / beste Weg, dies umzusetzen?
quelle
Antworten:
Ich habe völlig übersehen, wo Du duplizieren musst.
Ein zentrales Prinzip von Mikrodiensten besteht darin, dass der Dienst die einzige Behörde ist. Das heißt, Inventar und Benutzerverwaltung können vollständig getrennt werden. Ich würde die Benutzerverwaltung so gestalten, dass sie nicht einmal weiß, dass das Inventarsystem existiert.
Aber ich würde das Inventarsystem so gestalten, dass es nie etwas über andere Benutzer als eine Benutzer-ID speichert. Das behebt Ihr Problem bei der Weitergabe von Benutzerdatenänderungen.
Dinge, die sowohl Inventarinformationen als auch Benutzerinformationen benötigen, wie Protokolle, Audits und Ausdrucke, werden nicht aktualisiert, wenn sich die Informationen ändern. Sie sind eine Aufzeichnung dessen, was war. Auch hier propagiert man keine Veränderung.
Wenn Sie also in jedem Fall die neuesten Benutzerinformationen wünschen, wenden Sie sich an den Benutzerinformationsdienst.
quelle
It seems counter-intuitive to move from a single relational database where I could get the inventory data and the user data with a join
Denken Sie daran, dass es "idealerweise" ein Geschäft pro Service gibt (oder mehr!). Es gibt also nichts wie "Verbinden" zwischen "Grenzen". Der Grund ist einfach: DB generiert eine Kopplung zwischen Diensten. Im Gegensatz zu @CandiedOrange können wir meines Erachtens ein Minimum an Daten von einem Dienst zu einem anderen duplizieren. Ich beziehe mich auf Daten, die sich wahrscheinlich nicht ändern werden. Wenn dies die Effizienz und Leistung verbessert (und beides erforderlich ist), würden die "Profis" wahrscheinlich die "Nachteile"Laut dem Microsoft E-Book zur Microservice-Architektur ist an der Datenverdoppelung nichts auszusetzen. Grundsätzlich wird durch das Duplizieren von Daten die Entkopplung zwischen den Diensten verstärkt und ihre Rolle als einzelne Behörde gestärkt. Eine relevante Passage:
quelle
In der Tat, ja.
Zugegeben, in einem Monolithen könnten Sie ein Inventarmodell haben, das Sie nach den relevanten Elementen abfragen, das in ein Benutzermodell einspeisen und dieselben Daten erhalten.
Oder Sie könnten noch weiter gehen, wenn Sie sie in derselben relationalen Datenbank haben und SQL schreiben, und die Datenbank die Inventar- und Benutzertabelle übernimmt, etwas magisch ist und Sie die Daten erhalten, nach denen Sie suchen.
Unabhängig davon , wie Sie es tun, irgendwo wird Code sein, der im Wesentlichen eine Liste von Benutzer - IDs aus dem Inventar - System holt, speist sie in das Benutzersystem und stellt eine Liste von Daten.
Die Frage, die Sie beantworten müssen, betrifft die Leistung und Wartung sowie andere "weiche" Eigenschaften.
Der Hauptvorteil von Microservices ist die Skalierung.Wenn Sie zehntausend Benutzer auf einem Computer haben und es etwas träge ist, können Sie einen weiteren Computer hinzufügen, und das System wird doppelt so schnell. Fügen Sie acht weitere hinzu und es ist zehnmal so schnell. (Lineare Skalierung ist wahrscheinlich optimistisch, aber es ist das Ideal und nicht so unvernünftig, darauf zu hoffen.)
Und das ist pro Service . Wenn das Inventarsystem der Engpass ist, wird es für mehr als nur Berichte über Benutzer verwendet. Sie können nur diesem Service weitere Computer hinzufügen . Die Maschinen können auch spezialisiert werden; Dieser Dienst benötigt viel Speicher, führt umfangreiche Berechnungen durch und benötigt mehr CPU.
Wenn Sie die Skalierung nicht benötigen, gibt es einen weiteren Vorteil von Microservices: Sie sind modular aufgebaut . Natürlich können monolithische Apps auch modular sein, und Sie haben eine normalisierte Datenbank und ... aber in der Praxis sind die Wände zwischen den Modulen im besten Fall wie Glaswände und im schlechtesten Fall wie Linien im Sand. Microservices sind durch massiven Stahl getrennt.
Wenn Ihr Benutzersystem buchstäblich in Brand gerät, hat dies keinerlei Auswirkungen auf Ihr Inventarsystem. Sie können keine hübschen Berichte darüber drucken, wer was auf Lager hat, aber Kunden können sicher Bestellungen aufgeben, wenn sie wissen, dass die auf Lager befindlichen Artikel dort sind.
Und Sie duplizieren Daten in Microservices nicht mehr als in einer relationalen Datenbank (*). In einer relationalen Datenbank können Sie einen Join ausführen, und das Äquivalent besteht darin, die Listen wie beschrieben im Code zusammenzuführen.
Sie können auch eine Ansicht hinzufügen . Das Äquivalent ist, einen neuen Dienst hinzuzufügen, der die Zusammenführung für Sie ausführt. das würde zu drei Anfragen führen; eins auf den neuen Dienst und dieser Dienst führt dann die ursprünglichen zwei aus. Relationale Datenbanken haben ausgefallene Dinge, die Ansichten optimieren und auf Serviceebene implementiert werden müssen. Du bekommst es nicht "kostenlos".
Das Zwischenspeichern unterscheidet sich von der Duplizierung von Daten darin, dass Sie, wenn zwei Werte nicht übereinstimmen, wissen, welcher falsch ist. Es wird häufig in Mikrodiensten verwendet, um die Verfügbarkeit auf Kosten der Konsistenz zu erhöhen (CAP-Theorem). Da relationale Datenbanken die Verfügbarkeit auf dem Altar der Konsistenz vollständig unterbieten, ist dies bei ihnen seltener der Fall. Ich würde sagen, dass an Microservices nichts anhaftet, was das Caching erleichtert, aber in der Praxis ist das Caching ein Hauptanliegen und erleichtert das Caching in Microservices .
(*) Wenn es Sinn macht, Daten in einem Microservice-Schwarm zu duplizieren, dann wäre es wahrscheinlich sinnvoll, in der entsprechenden relationalen Datenbank zu.
quelle