martedì 22 giugno 2021

In che modo Event Sourcing ti aiuta a tenere traccia dello stato della tua applicazione

James Walker

Maggio 24, 2021, 2: 00 pm EDT | 5 minuti di lettura

Shutterstock / whiteMocca Il sourcing di eventi è un’architettura software in cui le modifiche allo stato dell’applicazione vengono acquisite come una serie di “eventi memorizzati perennemente . ” Mentre la maggior parte dei sistemi espone solo il proprio stato corrente, il sourcing degli eventi crea un record completo di tutti gli stati precedenti.

The Fundamentals L’origine degli eventi è più spesso utilizzato con sistemi basati sul tempo o su processi lineari. Un’app per gli ordini in negozio potrebbe trasferire le transazioni tra gli stati “in sospeso”, “approvato” e “spedito”. La transizione tra ogni stato è un “evento” distinto nel ciclo di vita di quell’ordine.

Questo sistema potrebbe essere modellato utilizzando un database relazionale tradizionale :

order_id | stato_ordine ——— | ————- 1000 | APPROVATO Nella maggior parte dei sistemi, tuttavia, conoscere lo stato corrente non è sufficiente. Vuoi anche vedere quando l’ordine è stato approvato. Potremmo farlo aggiungendo campi extra:

order_id | order_created_time | order_approved_time | order_shipping_time ——— | ——————– | —————— — | ——————— 1000 | 2021 – 04 – 30 | 2021 – 05 – 01 | NULL Ora è chiaro che l’ordine è stato creato ad aprile 30 e approvato il 1 ° maggio; la sua spedizione è ancora in sospeso. Per molte applicazioni, questa struttura funziona bene. Tuttavia, può diventare restrittivo man mano che vengono aggiunti più stati.

Diamo ora un’occhiata a questo esempio ristrutturato per utilizzare il sourcing di eventi:

event_id | event_order_id | tipo_evento | event_timestamp ——— | ——————— | —————- | —————- 2 | 1000 | order.approved | 2021 – 05 – 01 1 | 1000 | order.created | 2021 – 04 – 30 Le transizioni di stato dell’ordine sono state separate in un registro eventi dedicato. Con questo modello, è banale aggiungere un nuovo tipo di evento in futuro. Se un cliente ha bisogno di annullare un ordine, possiamo scrivere un ordine . nel registro.

Il sourcing di eventi potrebbe essere utilizzato anche per tenere traccia dei dati sull’ordine stesso. Potresti aggiungere tipi di eventi per order.apply_discount o order.process_refund . Puoi registrare un evento in qualsiasi momento, creando un nuovo stato per l’ordine mantenendo accessibili i suoi stati precedenti.

Ricostruzione dello stato di un oggetto È possibile determinare lo stato corrente di un oggetto recuperando tutti gli eventi ad esso correlati. Se vuoi sapere se un ordine è stato approvato, controlla se la sua raccolta di eventi contiene un evento order.approved .

Puoi ricostruire stati storici esattamente allo stesso modo. Se hai bisogno di conoscere lo stato dell’ordine in una data particolare, recupera tutti gli eventi registrati in o prima di quel giorno.

L’origine degli eventi è un modello incrementale che traccia automaticamente la cronologia di un oggetto. Ogni modifica allo stato dell’oggetto deve essere acquisita come evento con data e ora. Quando si utilizza il sourcing degli eventi, si dispone del controllo automatico della versione e di un registro di controllo completo delle transizioni di stato.

Se è necessario ricostruire il cronologia, puoi eliminare tutti gli eventi creati dopo una determinata data. Immagina che l’account di un utente sia stato compromesso da un malintenzionato che ha intrapreso varie azioni per suo conto. In un sistema completamente generato dagli eventi, è possibile eliminare qualsiasi evento collegato a quell’utente in un periodo di tempo discutibile. Ciò ripristinerebbe il loro account in un buono stato.

Per preservare questa capacità, devi assicurarti che gli eventi siano immutabili. Una volta che un evento è stato registrato, non dovresti mai modificarne le proprietà. Se un evento necessita di aggiustamento, dovresti registrare un altro evento per effettuare la modifica.

L’immutabilità del sistema significa che puoi tranquillamente usarlo per viaggiare indietro nel tempo e ricostruire stati storici. Se volessi riprodurre il tuo database com’era due anni fa, potresti scartare tutti gli eventi registrati nel tempo intercorso.

Un altro vantaggio dell’origine degli eventi aumenta la visibilità sullo stato del sistema. Se un utente segnala un bug, puoi clonare il database, eliminare nuovi eventi e ripetere i passaggi da un punto positivo noto. L’analisi degli eventi registrati può aiutarti a individuare i bug nella tua base di codice.

Approvvigionamento di eventi nel mondo reale L’approvvigionamento di eventi ha la reputazione di essere complesso, ingombrante e complicato. Storicamente, il sourcing degli eventi è stato collegato ad applicazioni con requisiti di audit rigorosi e una comprovata necessità di riprodurre gli eventi.

Non deve essere necessariamente il caso però. Se sei uno sviluppatore esperto, probabilmente in passato hai implementato qualcosa di simile al sourcing di eventi. Qualsiasi sistema che tenga un registro degli “eventi”, come i tentativi di accesso dell’utente, le visite alle pagine del sito Web o le fasi di elaborazione degli ordini, gravita naturalmente verso un approccio originato dall’evento, anche se non ne stai implementando uno intenzionalmente. Un’implementazione deliberata del sourcing di eventi nel codice può essere complicata. Gli sviluppatori di solito presumono che i dati recuperati dai database siano una rappresentazione accurata dello stato corrente di un oggetto. Con il sourcing degli eventi, i dati recuperati hanno di per sé poco valore. È necessario “riprodurre” gli eventi nella propria base di codice per creare una rappresentazione dello stato.

L’origine degli eventi può causare sovraccarichi di prestazioni. Nell’esempio sopra, la creazione di una rappresentazione completa dell’oggetto order ora richiede il recupero di molti più dati. Nel modello tradizionale, un’unica selezione fornisce tutti i dati associati all’ordine.

Ci sono anche altri svantaggi. Nel caso in cui qualcosa vada storto, la ricerca degli eventi può essere più difficile da risolvere. Non è possibile scrivere una patch rapida o correggere manualmente il database. Dovrai eseguire la transizione con grazia degli schemi degli eventi assicurandoti che la cronologia storica rimanga intatta.

Combinazione di Event Sourcing e CQRS Il sourcing di eventi è comunemente combinato con CQRS (Command Query Responsibility Segregation). Questo modello sostiene la separazione dei comandi (che scrive i dati) da query (che legge i dati).

L’uso del sourcing di eventi richiede un grado di CQRS. I dati vengono scritti nel database tramite eventi. Il modello di scrittura è quindi estremamente semplice: è un registro di sola aggiunta unidirezionale degli eventi che si verificano. Gli eventi sono una manifestazione dei “comandi” descritti da CQRS.

Il modello di recupero dei dati è completamente indipendente. È possibile utilizzare il sistema di query più appropriato per recuperare gli eventi e sovrapporli allo stato corrente dell’applicazione. I comandi (eventi) trasferisce il sistema in un nuovo stato; le query espongono gli aspetti di stato richiesti dalla tua applicazione.

In altre parole, i modelli di lettura e scrittura non hanno consapevolezza di come le altre funzioni . Le entità nella tua base di codice (come un ordine) vengono memorizzate come una sequenza di eventi cronologici. Gli eventi memorizzati non possono essere reidratati nell’entità a cui appartengono senza la conoscenza di come viene derivato lo stato di tale entità. Tale conoscenza è implementata all’interno del modello di lettura (query), che riporta i dati nella tua applicazione.

Questa caratteristica consente al livello di persistenza di essere semplificato all’inserimento di un singolo record per ogni operazione. I dati archiviati non devono rappresentare con precisione un’entità particolare poiché il modello di query la manipolerà in un secondo momento. Ciò contrasta con un database relazionale “tradizionale” in cui i campi della tabella spesso sono strettamente allineati con le proprietà degli oggetti nella base del codice.

L’output del il modello di query è noto come proiezione . Una proiezione è una rappresentazione dei dati che utilizza una prospettiva diversa dal suo sistema di archiviazione. Quando si utilizza la creazione di eventi, i dati vengono memorizzati come un flusso di eventi ma proiettati in una rappresentazione dello stato corrente dell’applicazione. Quella rappresentazione è senza stato, immutabile e idempotente: la creazione della rappresentazione non modifica in alcun modo i dati dell’evento sottostante.

Una singola proiezione potrebbe necessità di interagire con diversi tipi di eventi diversi. Le proiezioni esaminano i dati in modo aggregato, in un modo che abbia senso per le funzioni dell’applicazione. Nel nostro esempio precedente, una proiezione dell’ordine potrebbe generare un oggetto contenente CreatedDate , Data di approvazione e ShippedData esaminando gli eventi associati all’ordine del soggetto.

Conclusione Il sourcing di eventi è un’architettura software specializzata con supporto innato per responsabilità, cronologia e ricreazione dello stato. Il modello può semplificare in modo significativo l’implementazione di applicazioni in cui queste qualità sono desiderabili.

Il sourcing di eventi può essere utile anche in altri scenari, sebbene rendimenti decrescenti può essere incontrato. L’adozione del sourcing di eventi richiede che gli sviluppatori implementino il codice per determinare lo stato corrente, aggiungendo overhead che non si verificano nei sistemi che memorizzano solo lo stato corrente nel loro database.

Il sourcing di eventi si combina al meglio con altre tecniche di architettura software come CQRS, il pattern di osservazione e la consistenza finale. Non è necessario utilizzare il sourcing di eventi in tutta la tua app: spesso, i singoli sottomoduli trarranno vantaggio dal sourcing di eventi mentre la maggior parte del tuo progetto si attacca a un database relazionale tradizionale.