Mein Szenario ist wie folgt.
Ich entwerfe ein System, mit dem Daten von verschiedenen Sensortypen empfangen und konvertiert und anschließend für die spätere Verwendung durch verschiedene Front-End- und Analysedienste beibehalten werden können.
Ich versuche, jeden Dienst so unabhängig wie möglich zu gestalten, aber ich habe einige Probleme. Das Team hat sich für einen DTO entschieden, den wir verwenden möchten. Die nach außen gerichteten Dienste (Empfänger von Sensordaten) empfangen die Daten auf eigene Weise, konvertieren sie dann in ein JSON-Objekt (das DTO) und senden sie an den Message Broker. Die Verbraucher der Nachrichten wissen dann genau, wie sie die Sensordatennachrichten lesen sollen.
Das Problem ist, dass ich das gleiche DTO in ein paar verschiedenen Diensten verwende. Ein Update muss an mehreren Stellen durchgeführt werden. Offensichtlich haben wir es so gestaltet, dass ein paar zusätzliche oder fehlende Felder im DTO vorhanden sind und es kaum Probleme gibt, bis die Dienste aktualisiert wurden, aber es nervt mich immer noch und ich fühle mich wie ich bin einen Fehler machen. Es könnte leicht zu Kopfschmerzen werden.
Mache ich eine falsche Systemarchitektur? Wenn nicht, wie kann ich das umgehen oder zumindest meine Sorgen lindern?
proto
Datei für gRPC oder dasavro
Schema für Kafka freizugeben und die DTOs in beiden Diensten zu generieren, aber ich würde keine gemeinsam genutzte Bibliothek zwischen zwei Projekten freigeben.Antworten:
Mein Rat? Teilen Sie diese DTOs nicht mit den Anwendungen in einer Bibliothek. Oder zumindest jetzt nicht.
Ich weiß, scheint sehr kontraintuitiv. Du duplizierst Code, richtig? Dies ist jedoch keine Geschäftsregel, sodass Sie flexibler sein können.
Der Dienst, der das DTO sendet, muss in seinem Nachrichtenvertrag genau wie eine Rest-API festgelegt sein. Der Dienst kann das DTO nicht so ändern, dass die anderen Dienste, die bereits Informationen aus dem DTO verbrauchen, beschädigt werden.
Wenn ein neues Feld für DTO hinzugefügt wird, aktualisieren Sie die anderen Dienste, die dieses DTO verwenden, nur, wenn sie das neue Feld benötigen. Ansonsten vergiss es. Wenn Sie JSON als Inhaltstyp verwenden, haben Sie die Flexibilität, neue Attribute zu erstellen und zu senden, ohne den Code der Dienste zu unterbrechen, die diese neuen Felder in seinen aktuellen Versionen von DTO nicht abbilden.
Aber wenn Sie diese Situation wirklich stört, können Sie der Dreierregel folgen :
Warten Sie also etwas länger, bevor Sie dieses DTO für die Dienste freigeben.
quelle
Auch bei Microservices sollten die Entwicklungszyklen der Services unabhängig sein. *
Verschiedene SLDC und verschiedene Entwicklerteams
In einem echten MS-System könnten mehrere Teams an der Entwicklung des Ökosystems beteiligt sein, die jeweils für einen oder mehrere Dienste zuständig sind. Diese Teams wiederum befinden sich möglicherweise in verschiedenen Büros, Städten, Ländern, Plänen ... Vielleicht kennen sie sich nicht einmal, was den Austausch von Wissen oder Code (wenn möglich) sehr schwierig macht. Dies kann jedoch sehr praktisch sein, da gemeinsam genutzter Code auch eine Art Argumentation für die gemeinsame Nutzung impliziert. Was auch immer für ein bestimmtes Team sinnvoll ist, muss es nicht für ein anderes Team sein. Beispielsweise kann es für den DTO- Kunden in Abhängigkeit vom jeweiligen Dienst unterschiedlich sein , da Kunden von jedem Dienst unterschiedlich interpretiert (oder gesehen) werden.
Unterschiedliche Bedürfnisse, unterschiedliche Technologien
Mit isolierten SLDCs können Teams auch den Stapel auswählen, der ihren Anforderungen am besten entspricht. Das Auferlegen von DTOs, die in einer bestimmten Technologie implementiert sind, schränkt die Auswahlmöglichkeiten der Teams ein.
DTOs sind weder Geschäftsregeln noch Dienstleistungsverträge
Was sind eigentlich DTOs? Einfache Objekte mit keinem anderen Ziel als dem Verschieben von Daten von einer Seite zur anderen. Taschen von Gettern und Setzern. Es ist nicht die Art von "Wissen", das es wert ist, wiederverwendet zu werden, insgesamt, weil es überhaupt kein Wissen gibt. Ihre Volatilität macht sie auch zu schlechten Kandidaten für eine Kopplung.
Entgegen der Aussage von Dherik muss es einem Dienst möglich sein, seine DTOs zu ändern, ohne dass andere Dienste gleichzeitig geändert werden müssen. Dienstleistungen sollten seine tolerant Leser, tolerant Schriftsteller und tolerant scheitern . Andernfalls verursachen sie eine Kopplung auf eine Weise, die die Dienstarchitektur sinnlos macht. Noch einmal, und im Gegensatz zu Dheriks Antwort, ist es wahrscheinlich, dass während der Zerlegung der Dienste etwas schief gelaufen ist, wenn drei Dienste genau dieselben DTOs benötigen.
Unterschiedliches Geschäft, unterschiedliche Interpretationen
Es könnte (und wird) Querschnittskonzepte zwischen den Diensten geben, aber das bedeutet nicht, dass wir ein kanonisches Modell auferlegen müssen, um alle Dienste zu zwingen, diese auf die gleiche Weise zu interpretieren.
Fallstudie
Nehmen wir an, unser Unternehmen hat drei Abteilungen: Kundendienst , Verkauf und Versand . Angenommen, jede dieser Versionen gibt einen oder mehrere Dienste frei.
Kundendienst aufgrund seiner Domain Sprache , implementiert Dienstleistungen rund um das Konzept der Kunden, wo die Kunden sind Personen . Beispielsweise werden Kunden als Name , Nachname , Alter , Geschlecht , E-Mail , Telefon usw. modelliert .
Angenommen, Vertrieb und Versand modellieren ihre Dienste auch entsprechend ihrer jeweiligen Domänensprache. In dieser Sprache ist der Begriff Kunde erscheint auch , aber mit einem feinen Unterschied. Für sie Kunden sind nicht (unbedingt) Personen . Für den Verkauf sind Kunden eine Belegnummer, eine Kreditkarte und eine Rechnungsadresse , für den Versand auch ein vollständiger Name und eine Lieferadresse .
Wenn wir Vertrieb und Versand dazu zwingen, das kanonische Datenmodell des Kundenservice zu übernehmen , zwingen wir sie dazu, mit unnötigen Daten umzugehen, was zu unnötiger Komplexität führen kann, wenn sie die gesamte Darstellung beibehalten und die Kundendaten mit dem Kundenservice synchron halten müssen .
Ähnliche Links
* Hier liegen die Stärken dieser Architektur
quelle
Sie sollten Ereignisse veröffentlichen . Ereignisse sind bestimmte Arten von Nachrichten, die eine solide Tatsache über etwas darstellen, das zu einem bestimmten Zeitpunkt passiert ist.
Jeder Dienst sollte eine genau definierte Verantwortung haben und die Verantwortung für die Veröffentlichung der Ereignisse im Zusammenhang mit dieser Verantwortung haben.
Darüber hinaus möchten Sie, dass Ihre Ereignisse geschäftsbezogene Ereignisse und keine technischen Ereignisse darstellen. ZB lieber
OrderCancelled
Event alsOrderUpdated
mitstatus: "CANCELLED"
.Auf diese Weise muss ein Service, der auf eine stornierte Bestellung reagieren muss, nur einen bestimmten Nachrichtentyp abhören, der nur für dieses Ereignis relevante Daten enthält. ZB
OrderCancelled
braucht ein wahrscheinlich nur einorder_id
. Welcher Dienst, der darauf reagieren muss, hat bereits alles, was er über die Bestellung wissen muss, in einem eigenen Datenspeicher abgelegt.Hätte der Dienst jedoch nur
OrderUpdated
Ereignisse zum Abhören, müsste er den Ereignisfluss interpretieren, und es sei nun abhängig, dass der Lieferauftrag korrekt abgeschlossen wird, wenn ein Auftrag storniert wird.In Ihrem Fall jedoch als Sensordaten veröffentlichen, es Sinn machen könnte einen Dienst haben, hört auf die Ereignisse und veröffentlicht einen neuen Strom von „Business - Event“, zum Beispiel
TemperatureThresholdExceeded
,TemperatureStabilised
.Und seien Sie vorsichtig, wenn Sie zu viele Microservices erstellen. Microservices können eine großartige Möglichkeit sein, Komplexität zu verkapseln. Wenn Sie jedoch keine geeigneten Servicegrenzen entdecken, liegt Ihre Komplexität in der Serviceintegration. Und das ist ein Albtraum.
Es ist besser, zu wenige, zu große Dienste zu haben, als zu viele, zu kleine Dienste zu haben.
quelle