Microservices: Umgang mit Fremdschlüsselbeziehungen

78

Die Microservices-Architektur schlägt vor, dass jeder Dienst seine eigenen Daten verarbeiten sollte. Daher sollte jeder Dienst (Dienst A), der von Daten eines anderen Dienstes (Dienst B) abhängig ist, auf diese Daten nicht durch direkte DB-Aufrufe zugreifen, sondern über die vom zweiten Dienst (Dienst B) bereitgestellte API.

Was schlagen die Best Practices von Microservices zur Überprüfung von Fremdschlüsseleinschränkungen vor?

Beispiel: Ich entwickle eine Lieferfunktion (Microservice 1) für Produkte und bestimmte Produkte können nur an bestimmte Standorte geliefert werden, wie in der Produkttabelle angegeben, auf die nur Produkte zugreifen können (Mikroservice 2).

Wie stelle ich sicher, dass Microservice 1 (dh Zustellfunktion) eine Bestellung nicht an einen nicht gewarteten Ort bringt? Ich habe diese Frage, weil die Lieferfunktion nicht direkt auf die Produktdatenbank zugreifen kann. Daher gelten auf DB-Ebene keine Einschränkungen, wenn ein Lieferauftrag in die Lieferdatenbank gestellt wird (es ist keine Überprüfung möglich, ob eine Fremdschlüsselübereinstimmung in der Produktdatenbank vorhanden ist oder Tabelle).


quelle

Antworten:

68

Es ist möglich, eine gemeinsam genutzte Datenbank für mehrere Mikrodienste zu verwenden. Die Muster für die Datenverwaltung von Microservices finden Sie unter folgendem Link: http://microservices.io/patterns/data/database-per-service.html . Übrigens ist es ein sehr nützlicher Blog für die Microservices-Architektur.

In Ihrem Fall bevorzugen Sie die Verwendung der Datenbank pro Dienstmuster. Dies macht Microservices autonomer. In dieser Situation sollten Sie einige Ihrer Daten auf mehrere Microservices duplizieren. Sie können die Daten für API-Aufrufe zwischen Microservices oder für asynchrone Nachrichten freigeben. Dies hängt von Ihrer Infrastruktur und der Häufigkeit von Datenänderungen ab. Wenn es sich nicht oft ändert, sollten Sie die Daten mit asynchronen Ereignissen duplizieren.

In Ihrem Beispiel kann der Lieferservice Lieferorte und Produktinformationen duplizieren. Der Produktservice verwaltet die Produkte und Standorte. Anschließend werden die erforderlichen Daten mit asynchronen Nachrichten in die Datenbank des Zustelldienstes kopiert (Sie können beispielsweise rabbit mq oder apache kafka verwenden). Der Lieferservice ändert die Produkt- und Standortdaten nicht, verwendet sie jedoch bei der Ausführung seiner Arbeit. Wenn sich der Teil der Produktdaten, der vom Lieferservice verwendet wird, häufig ändert, ist die Duplizierung von Daten mit asynchronem Messaging sehr kostspielig. In diesem Fall sollten Sie API-Anrufe zwischen Produkt und Lieferservice tätigen. Der Lieferservice fordert den Produktservice auf, zu prüfen, ob ein Produkt an einen bestimmten Ort geliefert werden kann oder nicht. Der Lieferservice fragt den Produktservice nach einer Kennung (Name, ID usw.) eines Produkts und eines Standorts. Diese Kennungen können vom Endbenutzer übernommen oder von Microservices gemeinsam genutzt werden. Da die Datenbanken von Microservices hier unterschiedlich sind, können wir keine Fremdschlüssel zwischen den Daten dieser Microservices definieren.

API-Aufrufe sind möglicherweise einfacher zu implementieren, aber die Netzwerkkosten sind bei dieser Option höher. Außerdem sind Ihre Dienste weniger autonom, wenn Sie API-Anrufe tätigen. In Ihrem Beispiel kann der Lieferservice seine Aufgabe nicht erfüllen, wenn der Produktservice nicht verfügbar ist. Wenn Sie die Daten mit asynchronem Messaging duplizieren, befinden sich die für die Zustellung erforderlichen Daten in der Datenbank von Delivery Microservice. Wenn der Produktservice nicht funktioniert, können Sie die Lieferung ausführen.

Ali Sağlam
quelle
1
Gute Antwort. Ich verwende API-Aufrufe, muss aber auch die Daten eines anderen Dienstes sortieren und paginieren. Kennen Sie den besten Ansatz für diesen Fall?
Tranceholic
4
Sie sollten die Parameter für Paging und Sortierung zu Ihrer API hinzufügen. Dann übernehmen die Verbraucher der API die Verantwortung dafür, die richtige Seite mit der richtigen Bestellung zu erhalten. Es gibt einige Technologien, die zum Definieren einer API wie GraphQL verwendet werden. Soweit ich weiß, verfügen diese Technologien bereits über Sortier- und Paginierungsfunktionen. Wenn Sie diese Art von Technologie nicht verwenden, können Sie einfach die Parameter von Ihrem Client abrufen und sie verwenden, um Ihre nach Seiten sortierten Daten zurückzugeben.
Ali Sağlam
Tolle Antwort!
TS
1
Aber behalten Sie den Fremdschlüssel? Beispiel: Jeder Blog-Beitrag enthält viele Kommentare. Monolith wird eine Kommentartabelle mit einem Fremdschlüssel für den Blog-Beitrag haben. Im Microservice werden wir jedoch zwei Services haben. Service 1: Post Microservie mit diesen Tabellenfeldern (PostID, Name, Inhalt) Service 2: Kommentare Microservie mit diesen Tabellenfeldern (CommentID, PostID, Cpmment) Die Frage ist: Benötigen wir "PostID" in Service 2 (Kommentare Microservice)? Ich denke die Antwort ist ja, da wir wissen müssen, welcher Kommentar zu welchem ​​Beitrag gehört. Ist mein Verständnis richtig?
Rakesh Mehra
1
Das Aufteilen eines Systems in Microservices ist eine völlig andere Geschichte. Wenn Sie sich jedoch dazu entschlossen haben, zwei Microservices wie Post und Kommentar zu erstellen, benötigen Sie eine Post-ID für den Microservice für Kommentare, da jeder Kommentar zu einem Post gehört. Dies bedeutet jedoch nicht, dass Sie FK zwischen diesen Tabellen definieren müssen. FK ist nur eine Einschränkung in der RDBMS-Welt, die zur Gewährleistung der Datenintegrität und -konsistenz beiträgt. Wenn Sie die Daten dieses Mikrodienstes in separaten Schemas speichern, können Sie FK nicht definieren, oder Sie können sogar die Daten in einer nosql-Datenbank speichern (was für Kommentare im Mikrodienst sinnvoll wäre), in der FK nicht anwendbar ist.
Ali Sağlam
23

Wenn Sie Ihren Code verteilen, um eine geringere Kopplung zu erreichen, möchten Sie die gemeinsame Nutzung von Ressourcen vermeiden, und Daten sind eine Ressource, die Sie nicht gemeinsam nutzen möchten.

Ein weiterer Punkt ist, dass nur eine Komponente in Ihrem System die Daten besitzt (für Statusänderungsvorgänge), andere Komponenten LESEN, aber NICHT SCHREIBEN können, Kopien der Daten haben können oder Sie ein Ansichtsmodell freigeben können, mit dem sie den neuesten Status abrufen können eines Objekts.

Durch die Einführung der referenziellen Integrität wird die Kopplung wieder eingeführt. Stattdessen möchten Sie für Ihre Primärschlüssel so etwas wie Guids verwenden. Diese werden vom Ersteller des Objekts erstellt. Der Rest dreht sich um die Verwaltung der eventuellen Konsistenz.

Weitere Informationen finden Sie in Udi Dahans Vortrag im NDC Oslo

Hoffe das hilft

Sean Farmar
quelle
2
Der Link für Udi Dahans Vortrag ist sehr interessant
Comencau
0

Ein 2020-Update für diese Antwort besteht darin, ein Tool zur Datenerfassung wie Debezium zu verwenden. Debezium überwacht Ihre Datenbanktabellen auf Änderungen und überträgt sie an Kafka / Pulsar (andere Pipes). Ihre Abonnenten können die Änderungen dann erfassen und synchronisieren.

user521990
quelle