Warum Event Sourcing das Gegenmuster für die Interaktion mit Microservices ist

Hallo wieder. Im März startet OTUS den nächsten Stream des Software Architect- Kurses . Im Vorfeld des Kursbeginns haben wir eine Übersetzung von nützlichem Material für Sie vorbereitet.




In jüngster Zeit sind ereignisgesteuerte Architekturen (ereignisgesteuerte Architekturen) und insbesondere Event Sourcing (die Generierung von Ereignissen) weit verbreitet. Dies ist auf den Wunsch zurückzuführen, nachhaltige und skalierbare modulare Systeme zu schaffen. In diesem Zusammenhang wird häufig der Begriff „Microservices“ verwendet. Microservices sind meiner Meinung nach nur eine der Möglichkeiten, einen „ Bounded Contextzu implementieren . Es ist sehr wichtig, die Grenzen der Module richtig zu definieren, und das von Eric Evans in Domain Driven Design beschriebene strategische Design hilft dabei . Es hilft Ihnen, Module und Grenzen zu identifizieren / zu erkennen („eingeschränkter Kontext“) und zu beschreiben, wie diese Kontexte zueinander in Beziehung stehen (Kontextkarte, ContextMap).

Domänenereignisse als Grundlage einer einzigen Sprache


Obwohl dies in Eric Evans 'Buch nicht explizit angegeben ist, tragen Domain-Ereignisse sehr gut zu DDD-Konzepten bei. Praktiken wie Event Storming Alberto Brandolini verlagern den Fokus von Events von der technischen auf die organisatorische und geschäftliche Ebene. Hier geht es nicht um Ereignisse der Benutzeroberfläche, wie z. B. einen Klick auf eine Schaltfläche (ButtonClickedEvent), sondern um Domänenereignisse, die Teil des Themenbereichs sind. Sie werden von Experten auf dem Fachgebiet besprochen und verstanden. Diese Veranstaltungen sind die Hauptkonzepte und tragen zur Bildung einer einzigen Sprache ( allgegenwärtige Sprache ) bei, der alle Teilnehmer (Fachexperten, Entwickler usw.) zustimmen werden.

Domänenereignisse, die zur Kommunikation zwischen Kontexten verwendet werden


Domänenereignisse können verwendet werden, um zwischen eingeschränkten Kontexten zu interagieren. Angenommen, wir haben einen Online-Shop mit drei Kontexten: Bestellung (Lieferung), Lieferung (Lieferung), Rechnung (Konto).

Betrachten Sie das Ereignis "Bestellung angenommen" im Kontext der Bestellung. Der Rechnungskontext sowie der Übermittlungskontext sind daran interessiert, dieses Ereignis zu verfolgen, da dieses Ereignis einige interne Prozesse in diesen Kontexten auslöst.

Der Mythos der schwachen Konnektivität


Die Verwendung von Domänenereignissen hilft bei der Entwicklung lose gekoppelter Module. Einzelne Module sind möglicherweise vorübergehend nicht verfügbar. Für ein Domain-Ereignis ist es jedoch absolut nicht wichtig, ob sie verfügbar sind oder nicht, da das Ereignis nur beschreibt, was in der Vergangenheit passiert ist. Andere Module entscheiden, wann das Ereignis verarbeitet werden soll. Sie erhalten standardmäßig ein flexibles System.

Neben der zeitlichen Entkopplung bieten Domain-Ereignisse einen weiteren Vorteil: Der Auftragskontext muss nicht wissen, dass der Kontext der Rechnungen und Lieferungen auf seine Ereignisse abhört. Tatsächlich muss er nicht einmal wissen, dass diese Kontexte existieren.

Es ist großartig, aber die Schwierigkeit liegt in der Entscheidung, welche Daten in der Veranstaltung gespeichert werden sollen.

Die einfache Antwort: Event Sourcing!


Ereignisse sind nützlich. Warum also nicht maximal nutzen? Dies ist die Hauptidee von Event Sourcing . Sie speichern den Status des Geräts nicht durch Aktualisieren seiner Daten (CRUD), sondern durch Verwendung eines Ereignisstroms.
Neben der Tatsache, dass Sie Ereignisse abspielen und den Status abrufen können, gibt es eine weitere Funktion von Event Sourcing: Sie erhalten kostenlos ein vollständiges Überwachungsprotokoll. Wenn ein solches Protokoll erforderlich ist, achten Sie daher bei der Auswahl einer Speicherstrategie unbedingt auf die Ereignisbeschaffung.

Event Sourcing ist nur eine Speicherebene


Es mag Ihnen seltsam erscheinen, dass ich sofort von Domänenereignissen zu Speicher gewechselt habe, da dies offensichtlich Konzepte auf verschiedenen Ebenen sind.

... und hier ist mein Punkt: Event Sourcing ist eine lokale Lösung, die nur in einem begrenzten Kontext verwendet wird! Event Sourcing Events sollten nicht nach außen gezogen werden! Andere eingeschränkte Kontexte müssen nicht wissen, wie die Daten des jeweils anderen gespeichert werden. Daher spielt es keine Rolle, ob in einem bestimmten Kontext Event Sourcing verwendet wird.

Wenn Sie Event Sourcing global verwenden, geben Sie Ihre Speicherebene an.

Die Datenspeichermethode wird zu Ihrer öffentlichen API. Jedes Mal, wenn Sie Änderungen an der Speicherebene vornehmen, müssen Sie eine Änderung in der öffentlichen API vornehmen.

Ich bin sicher, jeder wird zustimmen, dass es schlecht ist, wenn verschiedene begrenzte Kontexte aufgrund der daraus resultierenden Konnektivität Daten in einer (relationalen) Datenbank gemeinsam nutzen. Aber wie unterscheidet sich das von Event Sourcing? Nichts. Es spielt keine Rolle, ob Sie freigegebene Ereignisse oder freigegebene Tabellen in der Datenbank verwenden. In beiden Fällen teilen Sie die Speicherdetails.

Es gibt einen Ausgang


Ich behaupte immer noch, dass Domänenereignisse ideal für die Interaktion zwischen begrenzten Kontexten sind, aber diese Ereignisse sollten nicht mit den Ereignissen zusammenhängen, die für die Ereignisbeschaffung verwendet werden.

Die vorgeschlagene Lösung ist sehr einfach: Unabhängig davon, welchen Ansatz Sie zum Speichern von Daten verwenden (CRUD oder Event Sourcing), veröffentlichen Sie Domänenereignisse im globalen Ereignisspeicher. Diese Ereignisse stellen die öffentliche API Ihres Kontexts dar. Wenn Sie Event Sourcing verwenden, speichern Sie Event Sourcing-Ereignisse in Ihrem lokalen Geschäft, auf das nur für diesen eingeschränkten Kontext zugegriffen werden kann.

Wahlfreiheit


Wenn Sie separate Domänenereignisse in der öffentlichen API haben, können Sie diese flexibel modellieren. Sie sind nicht auf ein Modell beschränkt, das von Event Sourcing vordefiniert wird.

Es gibt zwei Möglichkeiten, mit „realen Ereignissen“ zu arbeiten: einen Open Protocol-Dienst und eine öffentliche Sprache (Open Host-Dienst, veröffentlichte Sprache) oder einen Kunden / Lieferanten.

Dienst mit einem offenen Protokoll und einer öffentlichen Sprache (Open Host Service, veröffentlichte Sprache)


Es wird nur ein Domänenereignis veröffentlicht, das alle Daten enthält, die andere eingeschränkte Kontexte möglicherweise benötigen. In der DDD-Terminologie kann dies als Open Host Service und als veröffentlichte Sprache bezeichnet werden.



Der Beginn des realen Ereignisses "Order Accepted" führt zur Veröffentlichung eines OrderAccepted- Domain-Ereignisses . Die Nutzdaten dieses Ereignisses enthalten alle Bestelldaten, die andere eingeschränkte Kontexte möglicherweise benötigen. Hoffentlich finden die Kontexte "Rechnung" und "Lieferung" alle benötigten Informationen.

Kunden-Lieferanten


Für jeden Verbraucher werden separate Ereignisse veröffentlicht. Es ist erforderlich, die Modelle jedes Ereignisses mit nur einem Verbraucher zu koordinieren, und es ist nicht erforderlich, ein gemeinsames Modell zu bestimmen. DDD nennt diese Beziehung Kunde / Lieferant.



Das Auftreten realer Ereignisse „Bestellung angenommen“ führt zur Veröffentlichung einzelner Ereignisse für jeden Verbraucher: InvoiceOrderAcceptedund DeliveryOrderAccepted. Jedes Domänenereignis enthält nur die Daten, die für den Empfängerkontext erforderlich sind.

Ich möchte jetzt nicht auf die Vor- und Nachteile dieser Ansätze eingehen. Ich möchte nur darauf aufmerksam machen, dass Sie die Anzahl der Domänenereignisse und die darin gespeicherten Daten auswählen können.

Dies ist ein Vorteil, den Sie nicht unterschätzen sollten, da Sie entscheiden können, wie die API Ihres eingeschränkten Kontexts entwickelt werden soll, ohne an Event Sourcing-Ereignisse gebunden zu sein.

Fazit


Das Freilegen von Lagerteilen ist ein bekanntes Anti-Muster. In Bezug auf die Speicherung denken wir hauptsächlich an Datenbanktabellen, aber wir haben gesehen, dass die für die Ereignisbeschaffung verwendeten Ereignisse nur eine weitere Möglichkeit zum Speichern von Daten sind. Daher ist es auch ein Anti-Muster, sie herauszugeben.


Übersetzung: "Ein guter Entwickler wie ein Werwolf hat Angst vor Silberkugeln."

Event Sourcing ist ein leistungsfähiger Ansatz, wenn es richtig (lokal) verwendet wird. Auf den ersten Blick scheint dies für ereignisorientierte Architekturen eine Silberkugel zu sein, aber wenn Sie genau hinschauen, können Sie sehen, dass dieser Ansatz zu einer starken Verbindung führen kann ... was Sie natürlich nicht wollen.

Verweise


Zusätzlich zu meiner persönlichen Erfahrung erhielt ich viel Inspiration von verschiedenen Artikeln und Konferenzen. Ich möchte die Präsentation von Eberhard Wolff „Eventbasierte Architektur und Implementierungen mit Kafka und Atom“ (Eventarchitektur und Implementierung mit Kafka und Atom) erwähnen. Insbesondere über Event Sourcing und welche Events sind , was im Kontext dieses Beitrags sehr relevant ist. Das Beispiel des Online-Shops wurde ebenfalls von diesem Vortrag inspiriert.

Wenn Sie weitere Informationen wünschen, können Sie auf diese Ressourcen verweisen:


: « : ».

All Articles