Ich habe kürzlich diesen ausgezeichneten Artikel über die Microservice-Architektur gelesen: http://www.infoq.com/articles/microservices-intro
Wenn Sie eine Webseite auf Amazon laden, arbeiten mehr als 100 Microservices zusammen, um diese Seite bereitzustellen.
In diesem Artikel wird beschrieben, dass die gesamte Kommunikation zwischen Microservices nur über eine API erfolgen kann. Meine Frage ist, warum es so schlimm ist zu sagen, dass alle Datenbank-Schreibvorgänge nur über eine API erfolgen können, aber Sie können direkt aus den Datenbanken der verschiedenen Mikrodienste lesen. Man könnte zum Beispiel sagen, dass nur wenige Datenbankansichten außerhalb des Mikrodienstes zugänglich sind, sodass das Team, das den Mikrodienst verwaltet, weiß, dass es, solange diese Ansichten intakt bleiben, die Datenbankstruktur seines Mikrodienstes so stark wie möglich ändern kann wollen.
Vermisse ich hier etwas? Gibt es einen anderen Grund, warum Daten nur über eine API gelesen werden sollten?
Es erübrigt sich zu erwähnen, dass mein Unternehmen bedeutend kleiner als Amazon ist (und dies auch immer sein wird) und die maximale Anzahl von Nutzern, die wir jemals haben können, bei etwa 5 Millionen liegt.
Antworten:
Datenbanken sind nicht sehr gut darin, Informationen zu verbergen, was durchaus plausibel ist, da es ihre Aufgabe ist, Informationen tatsächlich preiszugeben. Aber das macht sie zu einem miesen Werkzeug, wenn es um das Einkapseln geht. Warum möchten Sie eine Verkapselung?
Szenario: Sie binden mehrere Komponenten direkt an ein RDBMS und sehen, dass eine bestimmte Komponente zu einem Engpass für die Leistung wird, für den Sie möglicherweise die Datenbank denormalisieren möchten. Dies ist jedoch nicht möglich, da alle anderen Komponenten betroffen wären. Möglicherweise stellen Sie sogar fest, dass Sie mit einem Dokumentenspeicher oder einer Diagrammdatenbank besser zurechtkommen als mit einem RDBMS. Wenn die Daten von einer kleinen API gekapselt werden, haben Sie eine realistische Chance, diese API nach Bedarf erneut zu implementieren. Sie können transparent Cache-Ebenen einfügen und was nicht.
Das Fummeln mit der Speicherschicht direkt von der Anwendungsschicht ist das diametrale Gegenteil von dem, was das Prinzip der Abhängigkeitsinversion vorschlägt.
quelle
Was ist wichtiger und wichtiger an einem Mikrodienst: seine API oder sein Datenbankschema? Die API, denn das ist ihr Vertrag mit dem Rest der Welt. Das Datenbankschema ist einfach eine bequeme Methode zum Speichern der vom Dienst verwalteten Daten, die hoffentlich so organisiert sind, dass die Leistung des Mikrodienstes optimiert wird. Das Entwicklungsteam sollte jederzeit die Möglichkeit haben, dieses Schema zu reorganisieren oder auf eine völlig andere Datenspeicherlösung zu wechseln. Der Rest der Welt sollte sich nicht darum kümmern. Der Rest der Welt kümmert sich, wenn sich die API ändert, da die API der Vertrag ist.
Nun, wenn Sie in ihre Datenbank spähen gehen
Die letzten beiden Punkte können möglicherweise nicht auftreten, wenn Sie nur Lesezugriff erhalten, die anderen Punkte sind jedoch mehr als ein guter Grund. Gemeinsame Datenbanken sind eine schlechte Sache.
Für weniger erfahrene Entwickler (oder diejenigen, die nicht lernen) ist es üblich, die Datenbank als wichtiger als den Service zu betrachten, die Datenbank als die reale Sache und den Service nur als einen Weg, dorthin zu gelangen. Das ist der falsche Weg.
quelle
Microservice Architecture ist schwer zu beschreiben, aber die beste Möglichkeit, darüber nachzudenken, ist eine Verbindung zwischen komponentenorientierter Architektur und serviceorientierter Architektur. Software als Suite besteht aus vielen Kleinunternehmenskomponenten mit einer ganz bestimmten Geschäftsdomänenverantwortung. Ihre Schnittstelle zur Außenwelt entweder in bereitgestellten Diensten oder in erforderlichen Diensten erfolgt über eine API klar definierter Dienste.
Das Schreiben in und sogar das Lesen aus einer Datenbank außerhalb des Geschäftsbereichs Ihrer Komponenten widerspricht diesem Architekturstil.
Der Hauptgrund dafür ist, dass eine API, die über einen Dienst von einer anderen Softwarekomponente bereitgestellt wird, die begründete Erwartung hat, dass die API höchstwahrscheinlich abwärtskompatibel ist, wenn neue Versionen der Dienstbereitstellungskomponente verfügbar werden. Wenn ich Entwickler einer "Providing" -Komponente bin, muss ich mich nur um die Abwärtskompatibilität mit meiner API kümmern. Wenn ich weiß, dass es drei andere Entwicklungsteams gibt, die benutzerdefinierte Abfragen direkt für meine Datenbank geschrieben haben, ist mein Job viel komplizierter geworden.
Schlimmer noch, vielleicht ist das andere Team, das diese geschrieben hat, mitten im Sprint in einem kritischen Projekt und kann diese Änderung von Ihrer Komponente jetzt nicht akzeptieren. Jetzt wird die Softwareentwicklung für Ihre Komponente in einer Geschäftsdomäne, die Sie besitzen, durch die Entwicklung in einer anderen Geschäftsdomäne vorangetrieben.
Die vollständige Interaktion durch Dienste verringert die Kopplung zwischen verschiedenen Softwarekomponenten, sodass Situationen wie diese nicht so häufig auftreten. Wenn es um andere Komponenten geht, die eine Ansicht in der Datenbank verwenden, haben Sie mehr Möglichkeiten, die Ansicht abwärtskompatibel zu machen, wenn andere Benutzer Abfragen dazu geschrieben haben. Ich bin jedoch immer noch der Meinung, dass dies der Ausnahmefall sein und nur für die Berichterstellung oder Stapelverarbeitung erfolgen sollte, bei der eine Anwendung enorme Datenmengen einlesen muss.
Dies funktioniert natürlich gut in großen verteilten Teams, in denen Entwicklungsteams nach Geschäftsbereichen wie Amazon getrennt sind. Wenn Sie ein kleiner Entwicklungsbetrieb sind, können Sie dennoch von diesem Modell profitieren, insbesondere, wenn Sie sich schnell auf ein großes Projekt vorbereiten müssen, aber auch, wenn Sie mit Hersteller-Software zu tun haben.
quelle
In den letzten 20 Jahren habe ich einige große modulare Datenbankentwürfe gesehen, und ich habe das von David vorgeschlagene Szenario einige Male gesehen, in denen Anwendungen Schreibzugriff auf ihr eigenes Schema / ihre eigenen Tabellen und Lesezugriff auf ein anderes Schema / haben. Reihe von Tabellen. Am häufigsten können diese Daten, auf die eine Anwendung / ein Modul nur Lesezugriff erhält, als "Stammdaten" bezeichnet werden .
In dieser Zeit habe ich nicht die Probleme gesehen, die mir frühere Antworten nahe legen, und ich denke, es lohnt sich, die in den vorherigen Antworten angesprochenen Punkte genauer zu betrachten.
Ich bin mit diesem Kommentar einverstanden, mit der Ausnahme, dass dies auch ein Argument dafür ist, eine Kopie der Daten lokal für den Microservice zu lesen. Das heißt, die meisten ausgereiften Datenbanken unterstützen die Replikation. Daher können die "Stammdaten" ohne Entwickleraufwand physisch in die Microservice-Datenbank repliziert werden, wenn dies gewünscht oder erforderlich ist.
Einige erkennen dies in älteren Versionen möglicherweise als "Unternehmensdatenbank", die Kerntabellen in eine "Abteilungsdatenbank" repliziert. Ein Punkt hier ist, dass es im Allgemeinen gut ist, wenn eine Datenbank dies für uns mit eingebauter Replikation geänderter Daten tut (nur Deltas, in binärer Form und zu minimalen Kosten für die Quellendatenbank).
Wenn unsere Datenbankauswahl diese Standardreplikationsunterstützung nicht zulässt, können wir in eine Situation geraten, in der wir "Stammdaten" in die Microservice-Datenbanken verschieben möchten, was zu einem erheblichen Aufwand für Entwickler führen kann auch ein wesentlich weniger effizienter Mechanismus sein.
Für mich ist diese Aussage einfach nicht richtig. Die Denormalisierung ist eine "additive" Änderung und keine "brechende Änderung", und keine Anwendung sollte aufgrund der Denormalisierung brechen.
Die einzige Möglichkeit, eine Anwendung zu unterbrechen, besteht darin, dass der Anwendungscode so etwas wie "select * ..." verwendet und keine zusätzliche Spalte verarbeitet. Für mich wäre das ein Fehler in der Anwendung?
Wie kann eine Denormalisierung eine Anwendung stören? Klingt für mich nach FUD.
Ja, die Anwendung ist jetzt vom Datenbankschema abhängig, was impliziert, dass dies ein großes Problem sein sollte. Obwohl das Hinzufügen zusätzlicher Abhängigkeiten offensichtlich nicht ideal ist, ist es meiner Erfahrung nach kein Problem, eine Abhängigkeit vom Datenbankschema zu haben. Warum könnte dies der Fall sein? Habe ich gerade Glück gehabt?
Stammdaten
Das Schema, auf das ein Microservice normalerweise nur Lesezugriff haben soll, ist das, was ich als " Stammdaten " für das Unternehmen bezeichnen würde. Es verfügt über die Kerndaten, die für das Unternehmen wesentlich sind.
Historisch bedeutet dies, dass das Schema, von dem wir die Abhängigkeit hinzufügen, sowohl ausgereift als auch stabil ist (etwas grundlegend für das Unternehmen und unveränderlich).
Normalisierung
Wenn 3 Datenbankdesigner ein normalisiertes Datenbankschema entwerfen, erhalten sie dasselbe Design. Ok, es könnte einige 4NF / 5NF-Variationen geben, aber nicht viel. Außerdem gibt es eine Reihe von Fragen, die der Designer stellen kann, um das Modell zu validieren, damit der Designer sicher sein kann, dass er zu 4NF gekommen ist (Bin ich zu optimistisch? Haben die Leute Probleme, zu 4NF zu gelangen?).
update: Mit 4NF meine ich hier, dass alle Tabellen im Schema bis zu 4NF auf ihre höchste Normalform gebracht wurden (alle Tabellen wurden bis zu 4NF entsprechend normalisiert).
Ich glaube, der Normalisierungsentwurfsprozess ist der Grund, warum Datenbankdesigner im Allgemeinen mit der Idee vertraut sind, von einem normalisierten Datenbankschema abhängig zu sein.
Durch den Normalisierungsprozess wird der DB-Entwurf zu einem bekannten "richtigen" Entwurf, und die Abweichungen von diesem sollten aus Leistungsgründen denormalisiert werden.
Wenn 3 Programmierer einen Entwurf zur Implementierung (als Code) erhalten würden, wären 3 verschiedene Implementierungen zu erwarten (möglicherweise sehr unterschiedlich).
Für mich liegt möglicherweise eine Frage des "Glaubens an die Normalisierung" vor.
Brechen Schemaänderungen?
Denormalisierung, Hinzufügen von Spalten, Ändern von Spalten für eine größere Speicherkapazität, Erweitern des Designs mit neuen Tabellen usw. sind allesamt ununterbrochene Änderungen, und DB-Designer, die die 4. Normalform erreicht haben, werden davon überzeugt sein.
Breaking Changes sind offensichtlich möglich, indem Sie Spalten / Tabellen löschen oder den Breaking Type ändern. Möglich ja, aber praktisch habe ich hier überhaupt keine Probleme gehabt. Vielleicht, weil verstanden wird, was bahnbrechende Veränderungen sind und welche gut gemanagt wurden?
Es würde mich interessieren, Fälle zu hören, in denen Schemaänderungen im Kontext von gemeinsam genutzten Nur-Lese-Schemas unterbrochen werden.
Obwohl ich dieser Aussage zustimme, gibt es meiner Meinung nach eine wichtige Einschränkung, die wir von einem Enterprise Architect hören könnten: "Daten leben für immer" . Das heißt, während die API das Wichtigste sein könnte, sind die Daten auch für das gesamte Unternehmen ziemlich wichtig, und sie werden für eine sehr lange Zeit wichtig sein.
Wenn beispielsweise das Data Warehouse für Business Intelligence ausgefüllt werden muss, werden die Schema- und CDC-Unterstützung aus Sicht der Geschäftsberichte unabhängig von der API wichtig.
Probleme mit APIs?
Wenn APIs nun perfekt und einfach wären, wären alle Punkte umstritten, da wir immer eine API wählen würden, anstatt nur lokalen Lesezugriff zu haben. Die Motivation, auch nur den lokalen Lesezugriff in Betracht zu ziehen, besteht darin, dass möglicherweise Probleme bei der Verwendung von APIs auftreten, die durch den lokalen Zugriff vermieden werden.
API-Optimierung:
LinkedIn hat eine interessante Präsentation (ab 2009) zum Thema der Optimierung ihrer API und warum es ihnen auf ihrer Skala wichtig ist. http://www.slideshare.net/linkedin/building-consistent-restful-apis-in-a-highperformance-environment
Kurz gesagt, sobald eine API viele verschiedene Anwendungsfälle unterstützen muss, kann sie leicht in die Situation geraten, in der sie einen Anwendungsfall optimal und den Rest aus Netzwerk- und Datenbanksicht eher schlecht unterstützt.
Wenn die API nicht die gleiche Komplexität aufweist wie LinkedIn, können Sie problemlos die folgenden Szenarien abrufen:
Ja, wir können natürlich das Cachen zu APIs hinzufügen, aber letztendlich ist der API-Aufruf ein Remote-Aufruf und es gibt eine Reihe von Optimierungen, die Entwicklern zur Verfügung stehen, wenn die Daten lokal sind.
Ich vermute, es gibt eine Reihe von Leuten, die es so zusammenfassen könnten:
Diese Antwort ist viel zu lang. Entschuldigung !!
quelle
Die Statusverwaltung (möglicherweise eine Datenbank) kann im Container des Microservice bereitgestellt und über eine API verfügbar gemacht werden. Die Datenbank eines Microservice ist für andere Systeme außerhalb des Containers nicht sichtbar - nur für die API. Alternativ kann ein anderer Dienst (z. B. ein Cache) den Status über eine API verwalten. Es ist ein wesentlicher Unterschied in der Architektur, dass alle Abhängigkeiten des Microservice (außer API-Aufrufen zu anderen Diensten) in einem einzigen bereitstellbaren Container enthalten sind. Wenn man das nicht bekommt, gehe zurück und studiere die Architektur.
quelle