Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Anziché archiviare solo lo stato corrente dei dati in un database relazionale, archivia la serie completa di azioni eseguite su un oggetto in un archivio di sola aggiunta. L'archivio funge da sistema di record che è possibile usare per materializzare gli oggetti di dominio. Questo approccio può migliorare la controllabilità e le prestazioni di scrittura in sistemi complessi.
Importante
Event sourcing è un modello complesso che introduce compromessi significativi. Cambia la modalità di archiviazione dei dati, la gestione della concorrenza, l'evoluzione degli schemi e lo stato delle query. È costoso eseguire la migrazione verso o da una soluzione di Event Sourcing e, dopo aver adottato il modello, vincola le decisioni di progettazione future nelle parti del sistema che lo utilizzano. Adottare l'origine degli eventi quando i vantaggi, ad esempio la verificabilità e la ricostruzione storica, giustificano la complessità del modello. Per la maggior parte dei sistemi e la maggior parte delle parti di un sistema, la gestione dei dati tradizionale è sufficiente.
Contesto e problema
La maggior parte delle applicazioni funziona con i dati. L'applicazione archivia in genere lo stato più recente dei dati in un database relazionale e inserisce o aggiorna i dati in base alle esigenze. Ad esempio, nel modello di creazione, lettura, aggiornamento ed eliminazione (CRUD) tradizionale, un'applicazione legge i dati dall'archivio, li modifica e aggiorna lo stato corrente dei dati con i nuovi valori, in genere usando transazioni che bloccano i dati.
L'approccio CRUD è semplice e veloce per la maggior parte degli scenari. Tuttavia, nei sistemi a carico elevato, questo approccio presenta problemi:
Contesa di scrittura: Poiché gli aggiornamenti richiedono cicli di lettura-modifica-scrittura con blocco a livello di riga, le scritture simultanee nella stessa entità riducono le prestazioni e diventano un collo di bottiglia sotto carico.
Verificabilità: I sistemi CRUD archiviano solo lo stato più recente dei dati. Se non si implementa un meccanismo di controllo che registra i dettagli di ogni operazione in un log separato, si perde la cronologia dei dati.
Soluzione
Il modello di origine eventi definisce un approccio alla gestione delle operazioni sui dati generati da una sequenza di eventi. Ogni evento viene registrato in un archivio a sola aggiunta. Il codice dell'applicazione genera eventi che descrivono ogni azione eseguita sull'oggetto . In genere invia eventi a una coda in cui un processo separato, un gestore eventi, rimane in ascolto della coda e rende persistenti gli eventi in un archivio eventi. Ogni evento rappresenta una modifica logica all'oggetto, ad esempio AddedItemToOrder o OrderCanceled.
Gli eventi vengono mantenuti in un archivio eventi che funge da sistema di registrazione o dalla fonte dati autorevole sullo stato corrente dei dati. I gestori eventi aggiuntivi possono restare in ascolto di eventi specifici e intervenire in base alle esigenze. Ad esempio, i consumatori possono avviare attività che applicano operazioni agli eventi per altri sistemi o eseguire altre azioni associate necessarie per completare l'operazione. Il codice dell'applicazione che genera gli eventi viene separato dai sistemi che sottoscrivono gli eventi.
Ogni entità in un sistema di origine eventi ha un proprio flusso di eventi, ovvero la sequenza ordinata di eventi che registra ogni modifica a tale entità. In qualsiasi momento, le applicazioni possono leggere la cronologia degli eventi. Le applicazioni derivano lo stato corrente di un'entità riproducendo tutti gli eventi nel flusso. Questo processo è noto come riattivazione. Può verificarsi su richiesta quando l'applicazione gestisce una richiesta.
Le applicazioni in genere implementano viste materializzate perché è costoso leggere e riprodurre eventi. Le viste materializzate sono proiezioni di sola lettura dell'archivio eventi ottimizzate per l'esecuzione di query. Ad esempio, un sistema può mantenere una visualizzazione materializzata di tutti gli ordini dei clienti usati per popolare l'interfaccia utente. Quando l'applicazione aggiunge nuovi ordini, aggiunge o rimuove gli elementi nell'ordine o aggiunge informazioni sulla spedizione, l'applicazione genera eventi e un gestore aggiorna la visualizzazione materializzata.
Il diagramma seguente mostra una panoramica di questo modello combinato con il modello CQRS (Command Query Responsibility Segregation). Il livello presentazione legge da un archivio di sola lettura separato e scrive i comandi nei gestori dei comandi. I gestori dei comandi recuperano il flusso di eventi dell'entità dall'archivio eventi, eseguono la logica di business e inseriscono nuovi eventi in una coda. I gestori di eventi consumano eventi dalla coda e memorizzano eventi nello store eventi, aggiornano lo store di sola lettura o si integrano con gli sistemi esterni.
Scaricare un file di Visio di questa architettura.
Flusso di lavoro
Il flusso di lavoro seguente corrisponde al diagramma precedente:
Il livello di presentazione chiama un oggetto che legge da un archivio di sola lettura. Usa i dati restituiti per popolare l'interfaccia utente.
Il livello presentazione chiama i gestori comandi per eseguire azioni come creare un carrello o aggiungere un elemento al carrello.
Il gestore dei comandi carica l'entità recuperando il flusso di eventi dall'archivio eventi. Ad esempio, potrebbe recuperare tutti gli eventi del carrello. Riproduce tali eventi sull'entità per ricostruire lo stato corrente prima che si verifichi una nuova azione.
La logica di business viene eseguita e vengono generati gli eventi. Nella maggior parte delle implementazioni, gli eventi vengono inseriti in una coda o in un topic per decouplare i produttori di eventi e i consumatori di eventi.
I gestori degli eventi ascoltano eventi specifici e svolgono l'azione appropriata relativa a tale gestore. In questo esempio i gestori eventi esemplino le azioni seguenti:
Scrivere gli eventi nell'archivio eventi
Aggiornare un archivio di sola lettura ottimizzato per le query
Integrazione con sistemi esterni
Vantaggi del modello
Il modello Event Sourcing offre i seguenti vantaggi:
Gli eventi non sono modificabili ed è possibile archiviarli usando un'operazione di sola accodamento. L'interfaccia utente, il flusso di lavoro o il processo che avvia un evento può continuare e le attività che gestiscono gli eventi possono essere eseguite in background. La velocità effettiva di scrittura migliora, soprattutto per il livello di presentazione, perché le scritture di solo accodamento evitano la contesa di blocco a livello di riga, che si verifica nei sistemi che aggiornano sul posto.
Gli eventi sono oggetti semplici che descrivono un'azione che si verifica insieme ai dati associati necessari per descrivere l'azione rappresentata dall'evento. Gli eventi non aggiornano direttamente un archivio dati. I gestori eventi prelevano ed elaborano gli eventi registrati quando un gestore è disponibile e il sistema può gestire il carico. Usare gli eventi per semplificare l'implementazione e la gestione.
Gli eventi, in genere, hanno significato per gli esperti del settore, mentre il disallineamento di impedenza oggetto-relazionale può rendere difficile la comprensione delle tabelle di database complesse. Le tabelle sono costrutti artificiali che rappresentano lo stato corrente del sistema, non gli eventi che si verificano.
La funzione di origine eventi contribuisce a impedire conflitti generati da aggiornamenti simultanei in quanto evita la necessità di aggiornare direttamente gli oggetti nell'archivio dati. I gestori dei comandi ricostruiscono un'entità dal suo flusso di eventi per applicare regole aziendali prima di aggiungere nuovi eventi, quindi due gestori che caricano la stessa entità simultaneamente possono operare sullo stesso stato.
Ad esempio, ogni gestore vede cinque postazioni rimanenti e entrambi i gestori possono accettare una prenotazione. Gli archivi di eventi affrontano questo scenario utilizzando il controllo della concorrenza ottimistica e rifiutano un'accodamento se il flusso è cambiato dal momento in cui è stato letto. Dopo il rifiuto, il gestore ricarica l'entità, rivaluta e riprova.
L'archiviazione eventi a sola scrittura fornisce un audit trail che le applicazioni possono usare per monitorare le azioni eseguite su un archivio dati. Può rigenerare lo stato corrente come viste materializzate o proiezioni riproducendo gli eventi in qualsiasi momento e può aiutare a testare ed eseguire il debug del sistema.
Il requisito di usare eventi di compensazione per annullare le modifiche può fornire una cronologia delle modifiche invertite. Se il modello archivia solo lo stato corrente, questa cronologia non esiste. È anche possibile usare l'elenco di eventi per analizzare le prestazioni dell'applicazione, rilevare le tendenze del comportamento degli utenti e ottenere altre informazioni aziendali utili.
I gestori dei comandi generano eventi e le attività eseguono operazioni in risposta a tali eventi. È questa separazione tra le attività e gli eventi a garantire flessibilità ed estensibilità. Le attività conoscono il tipo di evento e i dati dell'evento, ma non l'operazione che attiva l'evento.
Più attività possono gestire ogni evento, in modo che possano integrarsi facilmente con altri servizi e sistemi che ascoltano solo nuovi eventi generati dallo store di eventi. Tuttavia, gli eventi di sourcing degli eventi sono in genere di basso livello e potrebbe essere necessario generare eventi di integrazione specifici.
Suggerimento
L'event sourcing viene comunemente combinato con il modello CQRS eseguendo le attività di gestione dei dati in risposta agli eventi e creando le viste dagli eventi archiviati. Usare questa combinazione per ridimensionare in modo indipendente le letture e le scritture perché l'inserimento di eventi in modalità solo aggiunta e le proiezioni ottimizzate per le interrogazioni operano separatamente.
Problemi e considerazioni
Quando si decide come implementare questo modello, tenere presente quanto segue:
Progettazione eventi: Progettare eventi per acquisire la finalità aziendale dietro ogni modifica oltre allo stato risultante. Ad esempio, nel sistema di prenotazione posti a sedere, un evento che registra due postazioni riservate è più prezioso di un evento che registra i posti rimanenti modificati in 42. Il primo evento indica cosa è successo. Il secondo evento indica solo lo stato risultante. Gli eventi incentrati sullo stato riducono l'archivio eventi a un log delle modifiche che non ha alcun significato aziendale. Gli eventi incentrati sulle finalità offrono proiezioni più dettagliate, audit trail significativi e flessibilità per creare nuovi modelli di lettura da eventi cronologici senza dover modificare l'ambiente di scrittura.
Coerenza finale: Il sistema è coerente solo quando crea viste materializzate o genera proiezioni di dati riproducendo eventi. Esiste un ritardo tra quando un'applicazione gestisce una richiesta e aggiunge eventi all'archivio eventi, quando gli eventi vengono pubblicati e quando i consumer gestiscono gli eventi. Durante questo periodo, nuovi eventi che descrivono ulteriori modifiche alle entità potrebbero arrivare allo store di eventi. Assicurarsi che i clienti comprendano che i dati sono alla fine coerenti e che il sistema è progettato per tenere conto della coerenza finale in questi scenari.
Eventi di controllo delle versioni: L'archivio eventi è l'origine permanente delle informazioni, quindi non è consigliabile aggiornare mai i dati dell'evento. L'unico modo per aggiornare un'entità o annullare una modifica consiste nell'aggiungere un evento di compensazione all'archivio eventi. Un evento di compensazione è un nuovo evento che inverte o corregge l'effetto di un evento precedente. Ad esempio, un
ReservationCanceledevento compensa un evento precedenteSeatsReserved. L'evento originale rimane nel flusso e l'evento di compensazione registra che è stato annullato.Questa immutabilità significa anche che, se un bug produce eventi errati, tali eventi vengono comunque mantenuti nell'archivio. La correzione del bug nel codice dell'applicazione non corregge gli eventi storici, pertanto potrebbe essere necessario anche usare eventi di compensazione o *upcasters* per gestire i dati errati durante il replay. Se lo schema (anziché i dati) degli eventi persistenti deve cambiare, ad esempio durante una migrazione, può essere difficile combinare eventi esistenti nell'archivio con la nuova versione.
È possibile usare le strategie seguenti singolarmente o in combinazione:
Deserializzazione tollerante: Progettare consumatori di eventi per ignorare campi sconosciuti e usare valori predefiniti per campi mancanti. Questo approccio gestisce le modifiche additive e non breaking, ad esempio l'aggiunta di un campo facoltativo, senza richiedere alcuna trasformazione degli eventi archiviati.
Controllo delle versioni degli eventi: Includere un identificatore di versione in ogni evento, come metadati nella busta evento o come parte del nome del tipo di evento. I consumatori utilizzano la versione per selezionare la logica di gestione appropriata.
Upcasting: Registrare le funzioni di trasformazione che convertono gli schemi evento meno recenti nello schema corrente durante il processo di deserializzazione. È possibile concatenare i upcaster in modo che il codice dell'applicazione debba gestire solo la versione più recente. Gli eventi archiviati rimangono invariati, mantenendo l'immutabilità.
Migrazione sul posto: Riscrivere gli eventi cronologici nel nuovo schema direttamente nell'archivio eventi. Questo approccio interrompe l'immutabilità e dovrebbe essere un'ultima risorsa perché rovina il registro di controllo.
Ordinamento eventi: Le applicazioni a thread multipli e più istanze di applicazioni possono archiviare eventi nell'archivio eventi. La coerenza degli eventi nell'archivio eventi e l'ordine degli eventi che influiscono sullo stato corrente di un'entità specifica sono fondamentali. L'aggiunta di un timestamp a ogni evento consente di evitare problemi. Un'altra pratica comune consiste nell'annotare ogni evento risultante da una richiesta con un identificatore incrementale. Se due azioni tentano contemporaneamente di aggiungere eventi per una stessa entità, l'archivio eventi può rifiutare un evento che corrisponde a un identificatore di entità e a un identificatore di evento esistenti.
Query sugli eventi: Non esiste alcun approccio standard o meccanismi esistenti, ad esempio query SQL, per la lettura di eventi per ottenere informazioni. Gli unici dati che è possibile estrarre sono un flusso di eventi usando un identificatore di evento come criteri. L'ID evento è generalmente associato a entità individuali. È possibile determinare lo stato corrente di un'entità solo riproducendo tutti gli eventi correlati allo stato originale di tale entità.
Opzioni dell'archivio eventi: Un archivio eventi può essere un database appositamente progettato per flussi di eventi solo in accodamento o un database relazionale o documentale di uso generale con una tabella solo in accodamento.
Gli archivi eventi predefiniti offrono supporto predefinito per attività come la lettura di un flusso in base a entità, concorrenza ottimistica e snapshot.
I database relazionali sono familiari e ampiamente disponibili, ma richiedono di creare questi comportamenti manualmente.
Poiché ogni entità ha un flusso di eventi indipendente, gli archivi eventi vengono partizioni in modo naturale in base all'ID entità, semplificando il ridimensionamento orizzontale o il partizionamento orizzontale quando necessario.
Importante
Non confondere un archivio eventi con un broker di messaggi del flusso di eventi. I broker di messaggi, ad esempio Apache Kafka, in genere non dispongono di query di flusso per entità e concorrenza ottimistica. Funzionano bene come livello di distribuzione per distribuire eventi alle proiezioni e ai consumer esterni, ma non sono un sostituto di un archivio eventi.
Ricreazione dello stato dell'entità: La lunghezza di ogni flusso di eventi influisce sulla modalità di gestione e aggiornamento del sistema. Se i flussi sono di grandi dimensioni, la riproduzione di ogni evento per ricostruire un'entità diventa costosa sia in termini di tempo che di risorse computazionali. Per ridurre questo costo, creare snapshot a intervalli specifici, ad esempio ogni N eventi. Uno snapshot è una rappresentazione serializzata dello stato dell'entità in un punto specifico nel flusso di eventi. Per reidratare l'entità, caricare lo snapshot più recente e riprodurre solo gli eventi che si verificano dopo di esso, piuttosto che riprodurre l'intero flusso dall'inizio. Quando si sceglie una frequenza di snapshot, bilanciare il costo di archiviazione degli snapshot rispetto al tempo risparmiato durante la riattivazione.
Annotazioni
Gli snapshot sono un'ottimizzazione, non una sostituzione per il flusso di eventi. Il flusso di eventi rimane l'origine della verità ed è possibile rigenerare gli snapshot in qualsiasi momento.
Gestione dei conflitti: Il controllo della concorrenza ottimistica impedisce scritture in conflitto nello stesso flusso di eventi, ma l'applicazione deve comunque gestire i conflitti che si estendono su più entità. Ad esempio, un evento che indica una riduzione dell'inventario delle scorte potrebbe arrivare nell'archivio dati mentre un cliente inserisce un ordine per tale articolo. Progettare il sistema per riconciliare queste situazioni, ad esempio avvisando il cliente o creando un ordine indietro.
Requisiti di Idempotenza: Il recapito di eventi ai consumatori avviene in genere almeno una volta, quindi i consumatori possono ricevere lo stesso evento più volte. I gestori eventi devono essere idempotenti in modo che l'elaborazione di un evento duplicato non modifichi il risultato. Ad esempio, se più istanze di un consumer elaborano eventi di prenotazione postazioni per mantenere un numero di postazioni disponibili, un evento di prenotazione duplicato deve comportare un solo decremento. Senza idempotenza, le proiezioni si allontanano dal flusso di eventi e gli effetti collaterali, ad esempio i pagamenti o le notifiche, si attivano più volte. Tenere traccia dell'ultimo numero di sequenza di eventi elaborato per ciascun consumer e ignorare i duplicati, oppure progettare mutazioni dello stato che siano intrinsecamente sicure da ripetersi.
Logica circolare: Tenere presente gli scenari in cui l'elaborazione di un evento richiede la creazione di uno o più nuovi eventi. Questa sequenza può comportare un ciclo infinito.
Test: Uno stile di test specifico si adatta meglio ai sistemi basati su eventi. Configurare gli eventi passati, emettere un comando e verificare i nuovi eventi generati. Questo approccio given-when-then testa la logica aziendale senza database, code o proiezioni. Sono tuttavia necessari anche test di integrazione per proiezioni, comportamenti di idempotenza e percorsi di evoluzione dello schema, che aggiunge superficie di test rispetto ai sistemi CRUD.
Dati personali e conformità alle normative: La natura non modificabile di un archivio eventi è in conflitto con le normative sulla protezione dei dati che richiedono l'eliminazione dei dati personali, ad esempio il diritto di essere dimenticati dalle leggi. L'eliminazione di eventi interrompe in modo definitivo l'integrità del flusso, quindi progettare tenendo conto di questa tensione fin dall'inizio.
Un approccio comune consiste nell'archiviare i dati personali all'esterno dell'archivio eventi e farvi riferimento in base all'identificatore negli eventi. Questo approccio consente l'eliminazione in modo indipendente senza influire sul flusso di eventi.
Quando non è possibile separare i dati personali dagli eventi, usare crypto-shredding. Crittografare i dati personali negli eventi usando una chiave per soggetto. Eliminare la chiave per rendere i dati irreversibili lasciando intatta la struttura dell'evento. Questo approccio comporta un sovraccarico di crittografia per ogni lettura e scrittura e richiede una gestione affidabile delle chiavi.
Quando usare questo modello
Usare questo modello quando:
Si vuole identificare l'intento, lo scopo o il motivo nei dati. Ad esempio, è possibile acquisire le modifiche a un'entità cliente come una serie di tipi di eventi specifici, ad esempio Moved home, Closed account o Defunto.
È necessario ridurre al minimo o completamente evitare aggiornamenti in conflitto per i dati.
Si desidera registrare gli eventi che si verificano, per riprodurre gli eventi per ripristinare lo stato di un sistema, per eseguire il rollback delle modifiche o per mantenere una cronologia e un log di controllo. Ad esempio, quando un'attività è costituita da più passaggi, potrebbe essere necessario eseguire azioni per ripristinare gli aggiornamenti e quindi riprodurre alcuni passaggi per riportare i dati in uno stato coerente.
L'applicazione usa già gli eventi come una caratteristica naturale del suo funzionamento, e l'event sourcing richiede uno sforzo minimo di sviluppo o implementazione aggiuntivo.
È necessario separare il processo di input o aggiornamento dei dati dalle attività necessarie per applicare queste azioni. Questa modifica potrebbe essere quella di migliorare le prestazioni dell'interfaccia utente o di distribuire eventi ad altri listener che agiscono quando si verificano gli eventi. Ad esempio, è possibile integrare un sistema di retribuzione con un sito Web per l'invio di spese. Sia il sito Web che il sistema di retribuzioni utilizzano eventi generati dall'archivio eventi in risposta ai dati aggiornati nel sito Web.
Si vuole che la flessibilità modifichi il formato dei modelli materializzati e dei dati delle entità se i requisiti cambiano o quando si usa CQRS ed è necessario adattare un modello di lettura o le visualizzazioni che espongono i dati.
Se si utilizza CQRS e la consistenza eventuale è accettabile mentre un modello di lettura viene aggiornato, oppure l'entità e la riidratazione dei dati da un flusso di eventi comportano un'accettabile riduzione delle prestazioni.
Questo modello potrebbe non essere adatto quando:
I sistemi hanno operazioni CRUD semplici che non richiedono la verificabilità, la riproduzione o la ricostruzione cronologica dello stato. Il sovraccarico operativo di un archivio eventi non è giustificato se l'unico requisito è le operazioni di lettura e scrittura dello stato corrente.
I prototipi, i prodotti minimi validi (MVP) o i sistemi hanno una breve durata prevista. L'investimento iniziale nella progettazione di eventi, nella strategia di evoluzione dello schema e nell'infrastruttura di proiezione raramente restituisce un ritorno in questi scenari.
I sistemi richiedono coerenza e aggiornamenti in tempo reale per le visualizzazioni dei dati. La consistenza eventuale tra lo store degli eventi e le proiezioni è intrinseca al sourcing di eventi.
Domini in cui i dati sono principalmente statici o per riferimento, ad esempio tabelle di ricerca o cataloghi. Questo tipo di modifiche ai dati cambia raramente e non trae vantaggio dalla cronologia delle modifiche.
I team non hanno esperienza nelle architetture guidate dagli eventi. Event sourcing cambia il modo di testare, fare debug e operare un sistema. L'adozione senza la conoscenza di base aumenta il rischio di antipattern che sono costosi da invertire.
Suggerimento
L'Event sourcing non deve essere una decisione tutto o niente per il tuo intero sistema. Applicarlo in modo selettivo alle parti del sistema più vantaggiose, ad esempio un libro mastro di pagamento o una pipeline di elaborazione degli ordini. Usare il tradizionale CRUD per le parti quando la complessità non è giustificata, ad esempio nella gestione dei profili degli utenti o nella configurazione dell'applicazione.
Progettazione del carico di lavoro
Valutare come usare il modello Event Sourcing per la progettazione di un carico di lavoro per soddisfare gli obiettivi e i principi trattati nei pilastri di Azure Well-Architected Framework. La tabella seguente fornisce indicazioni su come questo modello supporta gli obiettivi di ogni pilastro.
| Pilastro | Come questo modello supporta gli obiettivi di pilastro |
|---|---|
| decisioni di progettazione dell'affidabilità consentono al carico di lavoro di diventare resiliente a un malfunzionamento e assicurano che ripristini a uno stato completamente funzionante dopo che si verifica un guasto. | Questo modello può facilitare la ricostruzione dello stato se è necessario ripristinare gli archivi di stato perché si acquisisce una cronologia delle modifiche nei processi aziendali complessi. - Partizionamento dei dati - RE:09 Ripristino di emergenza |
| l'efficienza delle prestazioni consente al carico di lavoro soddisfare in modo efficiente le richieste tramite ottimizzazioni di ridimensionamento, dati e codice. | Questo modello, in genere combinato con CQRS, una progettazione di dominio appropriata e snapshot strategici, può migliorare le prestazioni del carico di lavoro grazie a operazioni atomiche di sola accodamento e l'evitamento del blocco del database per operazioni di scrittura e lettura. - Prestazioni dei dati PE:08 |
Se questo modello introduce compromessi all'interno di un pilastro, considerarli contro gli obiettivi degli altri pilastri.
Esempio
Un sistema di gestione conferenze deve tenere traccia del numero di prenotazioni completate per una conferenza. Tenendo traccia di questo numero, può verificare la disponibilità di postazioni quando un potenziale partecipante tenta di effettuare una prenotazione. Il sistema può archiviare il numero totale di prenotazioni per una conferenza in almeno due modi:
Il sistema può archiviare informazioni sul numero totale di prenotazioni come entità separata in un database che contiene informazioni di prenotazione. Quando i partecipanti effettuano o annullano prenotazioni, il sistema aumenta o diminuisce questo numero. Questo approccio è semplice in teoria, ma può causare problemi di scalabilità se un numero elevato di partecipanti tenta di prenotare postazioni durante un breve periodo di tempo. Ad esempio, questo picco si verifica in genere nell'ultimo giorno prima della chiusura del periodo di prenotazione.
Il sistema può archiviare informazioni sulle prenotazioni e gli annullamenti come eventi tenuti in un archivio eventi. Calcola il numero di posti disponibili ricostruendo questi eventi. Questo approccio può essere più scalabile a causa dell'immutabilità degli eventi. Il sistema deve leggere solo i dati dall'archivio eventi o accodare i dati all'archivio eventi. Non modifica mai le informazioni sugli eventi relative alle prenotazioni e agli annullamenti.
Il diagramma seguente illustra come usare l'event sourcing per implementare il sottosistema di prenotazione posti del sistema di gestione delle conferenze.
Scaricare un file di Visio di questa architettura.
Flusso di lavoro
Il flusso di lavoro seguente corrisponde al diagramma precedente:
L'interfaccia utente invia un comando per riservare postazioni per due partecipanti. Un gestore di comandi separato gestisce il comando . Il gestore dei comandi è una parte della logica che viene disaccoppiata dall'interfaccia utente ed è responsabile della gestione delle richieste inviate come comandi.
Il sistema costruisce un'entità che contiene informazioni su tutte le prenotazioni per la conferenza riproducendo gli eventi che descrivono prenotazioni e annullamenti. Questa entità è denominata
SeatAvailabilityed è contenuta all'interno di un modello di dominio che espone metodi per l'esecuzione di query e la modifica dei dati nell'entità.Suggerimento
Prendere in considerazione ottimizzazioni come gli snapshot in modo che non sia necessario riprodurre l'elenco completo degli eventi per ottenere lo stato corrente dell'entità. Gli snapshot mantengono una copia dell'entità memorizzata nella cache anche in memoria.
Il gestore dei comandi richiama un metodo esposto dal modello di dominio per effettuare le prenotazioni.
L'entità
SeatAvailabilitygenera un evento che contiene il numero di posti riservati. La volta successiva che l'entità applica gli eventi, usa tutte le prenotazioni per calcolare il numero di posti rimanenti.Il sistema aggiunge il nuovo evento all'elenco degli eventi presenti nell'archivio eventi.
Se un utente annulla un posto, il sistema segue un processo simile, ma il gestore dei comandi emette un comando che genera un evento di annullamento dei posti e lo aggiunge all'archivio eventi.
Il sistema può fornire una cronologia completa, o audit trail, delle prenotazioni e degli annullamenti per una conferenza utilizzando un archivio eventi. Gli eventi nell'archivio di eventi costituiscono il record esatto. Non è necessario rendere persistenti le entità in altro modo perché il sistema può riprodurre facilmente gli eventi e ripristinare lo stato in qualsiasi momento.
Passo successivo
- Modello CQRS: l'archivio di scrittura che fornisce l'origine permanente delle informazioni per un'implementazione CQRS è in genere basato su un'implementazione del modello di origine eventi. Il modello separa le operazioni che leggono i dati in un'applicazione dalle operazioni che aggiornano i dati usando interfacce separate.
Risorse della comunità
Mancata corrispondenza dell'impedenza relazionale a oggetti.
Event Sourcing, di Martin Fowler: la descrizione originale del modello 2005 che ha stabilito il vocabolario di base.
Documenti CQRS (PDF) di Greg Young: la risorsa definitiva su Event Sourcing e CQRS creata dal professionista che ha formalizzato entrambi i modelli.
" output is necessary.)
I modelli e le linee guida seguenti possono essere rilevanti anche quando si implementa questo modello:
Modello di visualizzazione materializzata: l'archivio dati usato in un sistema di event sourcing in genere non è adatto per query efficienti. Un approccio comune consiste invece nel generare visualizzazioni prepopolate dei dati a intervalli regolari o quando i dati vengono modificati.
Modello di transazione di compensazione: il sistema non aggiorna i dati esistenti in un archivio di origine eventi. Aggiunge invece nuove voci che passano lo stato delle entità ai nuovi valori. Per invertire una modifica, usa le voci di compensazione perché non può invertire la modifica precedente. L'articolo Modello di transazione di compensazione descrive come annullare il lavoro eseguito da un'operazione precedente.
Analisi del dominio per i microservizi: nei sistemi che usano la progettazione basata su dominio (DDD), l'entità proprietaria di un flusso di eventi è in genere un'aggregazione, un limite di coerenza che riceve comandi, applica regole business e genera eventi.