CQRS + Event Sourcing: (è corretto che) I comandi sono generalmente comunicati punto a punto, mentre gli Eventi di dominio sono comunicati tramite pub / sub?


12

Sto fondamentalmente cercando di avvolgere la mia testa attorno al concetto di CQRS e concetti correlati.

Sebbene CQRS non includa necessariamente la messaggistica e il sourcing di eventi, sembra essere una buona combinazione (come si può vedere con molti esempi / blogposts che combinano questi concetti)

Dato un caso d'uso per un cambio di stato per qualcosa (diciamo per aggiornare una domanda su SO), considerereste corretto il seguente flusso (come nella migliore pratica)?

Il sistema emette un UpdateQuestionCommand aggregato che potrebbe essere separato in un paio di comandi più piccoli: UpdateQuestion che è mirato alla radice aggregata delle domande e UpdateUserAction (per contare punti, ecc.) Mirato alla radice aggregata dell'utente. Questi vengono inviati in modo asincrono utilizzando la messaggistica point-to-point.

Le radici aggregate fanno la loro parte e, se tutto va bene, attivano rispettivamente gli eventi QuestionUpdated e UserActionUpdated, che contengono lo stato che viene esternalizzato a un negozio di eventi .. per essere persistente yadayada, solo per essere completo, non proprio il punto qui.

Questi eventi vengono anche inseriti in una coda / pub per la trasmissione. Qualsiasi abbonato (tra cui probabilmente uno o più proiettori che creano le viste di lettura) è libero di iscriversi a questi eventi.

La domanda generale: è davvero buona prassi che i Comandi vengano comunicati punto a punto (ovvero: il ricevitore è noto) mentre gli eventi vengono trasmessi (vale a dire: i destinatari sono sconosciuti)?

Supponendo quanto sopra, quale sarebbe il vantaggio / svantaggio di consentire la trasmissione dei comandi attraverso pub / sub anziché punto-punto?

Ad esempio: quando si trasmettono comandi durante l'utilizzo di Saga potrebbe essere un problema, poiché il ruolo di mediazione che una Saga deve svolgere in caso di fallimento di una delle radici aggregate viene ostacolato, perché la saga non sa con quali radici aggregate partecipano .

D'altra parte, vedo vantaggi (flessibilità) quando sono consentiti i comandi di trasmissione.


Domanda ben scritta tra l'altro.
Dav

Risposte:


19

Dichiarazione di non responsabilità: sto solo muovendo i miei primi passi nel mondo CQRS, ma posso offrire la mia attuale comprensione della questione e vedremo se gli altri confermano. Tutto ciò che scrivo di seguito ha un tema "come lo vedo" e non è autorevole.

Il caso dell'80%

Per rispondere alla tua domanda, i comandi sono davvero un punto per punto. Quando un comando entra in un controller (webapp MVC), quel controller chiede quindi a un dispatcher di comandi di trovare uno e un solo gestore di comandi appropriato e delega il lavoro a quel gestore.

Perché non pubblicare?

È una questione di responsabilità . Se qualcosa invia un comando, comporta l' aspettativa che venga adempiuto. Se pubblichi semplicemente e speri che qualcosa da qualche parte lo raccolga e agisca su di esso, non vi è alcuna garanzia che ciò accada. Per estrapolazione, non sai anche se più gestori non decidono di agire su un comando, con la conseguenza che la stessa modifica verrà applicata più di una volta.

Gli eventi, d'altra parte, sono di natura informativa ed è ragionevole aspettarsi che zero, due o più componenti siano interessati a un determinato evento. Non ci interessa davvero lo scopo di apportare la modifica richiesta.

Esempio

Questo potrebbe essere paragonato alla vita reale. Se hai tre figli, entra in una stanza e grida semplicemente "Pulisci il bagno", non hai alcuna garanzia che qualcuno lo farà e verifica se non sarà fatto due volte (se hai dei figli obbedienti che è ;-) Dovresti fai meglio se assegni a un bambino specifico di fare ciò che vuoi fare.

Tuttavia, quando quel bambino termina il suo lavoro, è conveniente se urla "il bagno è stato pulito", in modo che chiunque voglia lavarsi i denti sappia che ora può farlo.


Ha molto senso. Eccellente analogia :)
Geert-Jan

Mi hai perso a .. When a command enters a controller (MVC webapp)-? Stai usando RESTful? o alcuni endpoint API ibridi? Potresti aggiungere un esempio per favore
Piotr Kula,

@ppumkin abbiamo utilizzato un endpoint WebAPI che verrebbe chiamato dalla nostra app Web ogni volta che fosse necessario eseguire un comando. Per esempio. se l'utente volesse aggiungere un commento post, l'app Web avrebbe inviato una richiesta POST a example.com/api/Post/AddPostComment.
Dav

1

Sono d'accordo sul fatto che un sistema di avvio generalmente non si aspetterebbe mai che un comando venga eseguito da più sistemi di destinazione:

  • I comandi di solito non "inviano e pregano" mai - il sistema di avvio di un comando generalmente richiede un feedback asincrono man mano che il progresso e l'esito del comando hanno luogo (ad es. Eventi di stato come acknowledgement, e di successo completiono failurepossono essere pubblicati dal sistema mirato per informare l'iniziatore sistema).
  • Se fossero coinvolti più sistemi target, il sistema di avvio riceverebbe più risultati (possibilmente contraddittori) per il comando (ad es. Target 1 riuscito, ma target 2 fallito). Ciò richiederebbe un'ulteriore complessità nel determinare lo stato effettivo del comando originale (ad esempio, la transazione del comando sarebbe considerata riuscita solo se tutti gli obiettivi fossero riusciti? Il comando dovrebbe essere annullato o compensato in obiettivi riusciti se uno degli obiettivi fallisse? eccetera.). Ciò introdurrebbe accoppiamenti e complessità indesiderabili tra i sistemi di avvio e di destinazione.

Vi è tuttavia ancora del merito nel poter abbonarsi ulteriori consumatori (non transazionali e di solito piuttosto "promiscui") che "intercettano" i comandi emessi tra i sistemi

  • Scopi di revisione
  • Strumentazione e metriche operative (ad es. Carico, analisi aziendale, ecc.)
  • "Intercettazioni" complesse di elaborazione di eventi o eventi in streaming: questi sistemi sono in grado di rilevare errori o irregolarità nei comandi (ad es. Frequenza dei comandi o correlazione tra diverse combinazioni di comandi ed eventi) e possono attivare avvisi o azioni correttive (spesso forma di ulteriori, diversi tipi di comandi).
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.