2016-04-27 20 views
2

Gibt es eine gute Möglichkeit, CQRS in Kombination mit Event Sourcing zu verwenden?Wie geht man beim Event Sourcing mit Akka 2.4.x an das Q im CQRS heran?

Eine Möglichkeit, wie ich dies im Command-Handler (eines persistenten Actors) tun konnte, sobald der Befehl in ein Event umgewandelt und im Event-Log festgehalten wurde (diese Events repräsentieren das Write-Modell), würde ich senden das Ereignis, das den Ereignisbus für interessierte Subskribenten verwendet, damit diese ihr Abfragemodell aktualisieren können. Der andere Weg, den ich dachte (sofern das Journal dies unterstützt) ist die Verwendung von Persistenzabfragen (über Akka Streams) wie allPersistenceIds oder currentPersistenceIds und die Abfrageseite (mögliche Abfrageschauspieler) könnte dies in regelmäßigen Abständen durchführen.

Bin ich auf dem richtigen Weg? Gibt es einen besseren Weg?

+1

Lesen Sie den Arbeitscode in der letzten Antwort finden Sie hier: [link Beschreibung hier eingeben] (http://stackoverflow.com/questions/38246786/akka-persistence-query-event-stream -and-cqrs/43635674 # 43635674) –

+1

Der Arbeitscode wird hier gepostet: [hier] (http://stackoverflow.com/questions/38246786/akka-persistence-query-event-stream-and-cqrs/43635674# 43635674) –

+0

Vielen Dank Alex – Cal

Antwort

0

Nach einigen Recherchen und in Anerkennung der Tatsache, dass Aktualisierungen der Leseseite während der Bearbeitung des Befehls (erster Ansatz oben) fehlschlagen kann, die mit Rollback und Transaktion beinhalten würde tun. Ein besserer Ansatz besteht darin, die Persistenzabfrage zu verwenden. Dies hängt stark von Ihrem Event Journal ab, das die verschiedenen Funktionen der Persistence Query unterstützt (wie AllPersistenceIdsQuery und EventsByTag), die derzeit von Zeitschriften wie Cassandra, Event Store und einigen anderen unterstützt werden.

Die Idee ist, die Befehlsseite von der Abfrageseite (n) zu entkoppeln, wobei die Befehlsseite muss nicht wissen, gibt es jede Abfrage Seite (n) überhaupt. Diese Entkopplung erhalten Sie unter Persistence Query. Die Idee ist, dass die Command Side sich nur mit der Validierung eingehender Befehle und persistierender Ereignisse im Event Journal befassen sollte. Das ist es, kein Bewusstsein für die Abfrageseite.

Jetzt für die Query-Seite (n), verwenden Sie Persistence Query-wie EventsByTag oder AllPersistenceIdsQuery ein Source[Event] aus der Zeitschrift zu erhalten, die eine ist zurück-Druck Live-Stream von Event s aus dem Event-Journal und Sie verwenden diese Abstraktion um Ihre Read Sides zu füttern. Sie können Ansätze finden here

des

Was über Fehler denken lassen, wenn der Befehl Seite nach unten geht?

ohne neue Event s wird das Ereignis Journal beibehalten werden, die Lese-Seite Persistence Abfragen glücklich keine neue Event s im Strom entlang produziert wird tuckern. Wenn der Befehl Seiten wieder nach oben kommt, wird alles wieder aufnehmen und jetzt wird die Lese-Seite Persistence Abfragen neue Event s im Stream sehen.

Was passiert, wenn eine der Read Sides untergeht?

Kein großes Problem, Sie würden die gelesene Seite Datenbank löschen und starten diese Persistence Query von Anfang an und weg wir gehen. Wir können dies definitiv verbessern, indem wir das Konzept Resumable Projections verwenden.Die Idee ist, den aktuellen Offset von jedem gelesenen Event zu speichern, so dass, wenn Ihre Read Side ausfällt, wir einfach von dem Punkt, den wir gelesen haben, weitermachen können, anstatt den ganzen Weg von vorne beginnen zu müssen. Ein Ratschlag, wenn Sie effektiv-einmal Lieferung benötigen, dann möchten Sie möglicherweise mit Idempotenz-Filter untersuchen, um doppelte zu vermeiden. Wenn Sie dies tun, können Sie einige Optimierungen vornehmen, bei denen Sie nicht jede ID persistieren müssen, sondern nur in bestimmten Intervallen.

Einige andere Überlegungen

Was passiert, wenn Sie neue Leseseiten einführen müssen und sie hängen von Kommando Side Events von Anfang an?

Dieser entkoppelte Ansatz ermöglicht es Ihnen, dies zu tun. Die Idee ist, dass Sie keine Ereignisse aus dem Ereignisspeicher löschen, sondern einfach eine weitere Persistenzabfrage starten und Ihre neue Leseseite füttern. Vergessen Sie nicht, wiederaufladbare Projektionen zu verwenden, wenn Sie auf dem Laufenden bleiben müssen.

Diese Ansätze haben implizit impliziert Persistenzabfrage und die Logik, um die Read Side (s) und die fortsetzbare Projektion auf dem gleichen System zu füttern. Ein anderer Ansatz besteht darin, die Persistence Query mit Akka HTTP zu koppeln und einen Streaming-Endpunkt zu exponieren, der Ihr Event Journal verfügbar macht und Ihnen erlaubt, entweder alle Events/bestimmte Events von Anfang an oder ab einem bestimmten Offset zu erhalten. Auf diese Weise können Sie weitere Entkopplungen durchführen, aber wenn Sie diesen Ansatz verwenden, möchten Sie wirklich wiederaufsetzbare Projektionen haben, da der Fehler jetzt aufgrund der Einführung von HTTP erhöht wird. Jetzt können Ihre Read Sides diesen Streaming-Endpunkt konsumieren und die wiederaufnehmbare Projektion auf ihrer Seite haben und neue Read Sides können in einer entkoppelten Art und Weise eingeführt werden.

Dies sind nur einige meiner Erfahrungen, die ich gesammelt habe, seit ich mit Akka arbeite. Vielleicht haben einige erfahrenere Menschen bessere Ansätze für CQRS.

Wenn Sie nach Codebeispielen suchen, empfehle ich sehr, einen Blick auf Mastering Akka von Christian Baxter zu werfen, der den Ansatz in viel größerem Detail beschreibt und auch dieses post.

Vielen Dank für

+0

Siehe auch http://stackoverflow.com/questions/38246786/akka-persistence-query-event-stream-and-cqrs – Cal

3

Ich denke, der Ansatz, den Sie zuerst erwähnt haben, wird ohne Probleme funktionieren. Das würde ich für den zweiten nicht sagen. Wenn ich Sie richtig verstehe, möchten Sie, dass Ihre Abfrageprojektion nach Updates sucht, statt über einen Event-Bus weitergeleitet zu werden. Ich denke, das Problem besteht darin, dass Sie zwischen bereits verarbeiteten Ereignissen und neuen Ereignissen (Updates) unterscheiden müssen. Ich bin nicht sicher, ob das Akka EventStore Journal damit umgehen kann, aber ich würde das bezweifeln.

+0

Ich glaube, wenn Sie mit dem zweiten Ansatz gehen, müssten Sie die Abfrage von Grund auf neu erstellen, die nicht so schlimm ist, wie es klingt. Aber es könnte ziemlich anstrengend werden, wenn es viele Ereignisse gibt. Guter Punkt, danke für Ihren Einblick – Cal