Notifica di eventi e trasferimento di stato effettuato da eventi

Mentre ci spostiamo in un mondo in cui i sistemi distribuiti sono la norma e i monoliti l’eccezione, una delle decisioni architettoniche chiave da prendere riguarda i meccanismi della comunicazione tra i servizi. Sebbene le sfide della comunicazione sincrona siano ragionevolmente ben comprese (a meno che, naturalmente, non ti piaccia un tipo speciale di sfida e ti piacerebbe gestire un monolite distribuito), i punti decisionali su come la comunicazione asincrona è abilitata è ancora un po ‘oscuro. Questo post tenta di spingere su alcuni dei fattori che prendo in considerazione quando definisco il modello specificamente attorno agli eventi.

In questo post, supporremo che l’organizzazione implementi un microservizio “indirizzo” per gestire gli indirizzi dei suoi clienti e il suo utilizzo. Potrebbe trattarsi di indirizzi di fatturazione, indirizzo di spedizione o altri luoghi. L’esempio che prenderemo apparterrà a un cliente identificato da un ID cliente 911000100. Questo cliente aveva uno stato iniziale nel sistema di 4 indirizzi:

E ha apportato una modifica al suo indirizzo di fatturazione – una piccola correzione dell’errore di battitura fatto sul numero civico (da 84 a 48). Lo stato finale avrebbe dovuto essere

Notifica evento:

In questa modalità, il produttore dell’evento invia una notifica al sistema degli eventi che si è verificata una modifica all’entità. Ad esempio, nel caso del servizio indirizzi, l’evento riporterà solo le informazioni minime (“Il cliente 911000100 ha subito una modifica all’entità indirizzo”).

Questo può in alternativa essere perfezionato per fornire un po ‘più di metadati sulla modifica. Ad esempio: “Il cliente 911000100 ha modificato il suo indirizzo di fatturazione”

Nota che in entrambi questi scenari, la modifica stessa NON è stata specificata nell’evento. I consumatori dovrebbero interrogare l’endpoint di lettura per comprendere lo stato più recente dei dati.

Trasferimento di stato effettuato da eventi:

In netto contrasto con il modello di notifica degli eventi, il modello di trasferimento dello stato trasmesso dagli eventi inserisce i dati come parte dell’evento stesso.

Ci sono due varianti chiave per implementarlo. Grana fine e istantanee.

Grana Fine ha due opzioni:

2. Come istantanea del record specifico (il cliente 911000100 aveva in precedenza l’indirizzo di “fatturazione” come “84 Baker Street, Londra” e ora lo ha cambiato in “48 Baker Street, Londra”)

Istantanea:

Il secondo consiste nell’implementare istantanee del contesto principale che dovrebbero essere abilitate nella comunicazione tra processi. Come avrai notato negli esempi, il contesto del messaggio specifica l’ID del cliente anziché l’ID dell’indirizzo stesso. Ciò si baserebbe su una valutazione di ciò da cui i consumatori trarrebbero maggior vantaggio: una comprensione dei dati rispetto a un cliente specifico rispetto ai record di un’entità specifica ignorando il contesto più ampio in cui opera.

Prima di tutto un non negoziabile che deve essere integrato in tutti i consumatori, Idempotence :

Si dice che un servizio abbia la caratteristica di idempotenza se lo stesso input che gli viene lanciato più volte non cambia il suo stato inaspettatamente. Questo è un concetto applicabile all’informatica come alla matematica. Maggiori dettagli qui. In pratica, se la tua organizzazione impone l’utilizzo di ID di correlazione per le richieste (incl. Eventi), questo può essere ottenuto con una semplice introspezione sugli ID di correlazione già elaborati per farlo. Nel mondo degli eventi, ci sono pochissime piattaforme che hanno modalità che mirano alla consegna una volta sola (la maggior parte delle piattaforme offre una consegna almeno una volta). Questo dovrebbe sempre far parte dell’elenco di requisiti non negoziabili (altri in questa categoria includono il controllo e la registrazione, ne parleremo in un’altra occasione) quando crei il tuo servizio.

Criteri di valutazione

Capacità dei sistemi di consumo di gestire la consegna fuori ordine:

A differenza dell’idempotenza, la consegna fuori ordine è una bestia completamente diversa. Ciò richiede una capacità di introspezione molto più profonda all’interno del servizio o all’interno della pipeline di elaborazione. La garanzia dell’ordine dei messaggi è un’operazione costosa, quasi tutte le piattaforme di messaggistica distribuite non la offrono o hanno varianti specifiche che consentono un ordine FIFO più costoso (sia in termini di $ che di throughput. Inoltre, la configurazione della piattaforma richiederà un’attenta riflessione modelli di partizionamento). Questo è un fattore a cui attribuisco un peso significativo nella valutazione della decisione sulla notifica rispetto al trasferimento statale. Se è improbabile che le tue applicazioni che consumano prendano decisioni accurate per riordinare i messaggi / selezionare i messaggi da elaborare anziché ignorare, la notifica è di gran lunga l’approccio più semplice da adottare. Nel modello di notifica, la relazione tra l’ora dell’evento e il tempo di elaborazione è stata interrotta. Indipendentemente da quando un consumatore sceglie di consumare un evento, lo stato più recente del record viene recuperato dal proprietario dei dati. Supponendo che il sistema di consumo sia idempotente, questo può ora consentire ritardi significativi nell’elaborazione (che possono essere sfruttati per l’ottimizzazione nel batch) se la modalità è una notifica. Detto questo, si presume che il produttore di eventi disponga di un servizio di lettura altamente disponibile per consentire questa richiamata. In pratica, questo non è generalmente un problema, anche se è ancora qualcosa da tenere d’occhio, poiché la lettura può avvenire in qualsiasi momento in futuro, non solo l’ora dell’evento.

Batch:

Potrebbe esserci un’ottimizzazione delle prestazioni che preferiresti nella comunicazione con alcune applicazioni a valle. Ciò potrebbe essere dovuto a tutta una serie di motivi, comprese le soluzioni SaaS che si addebitano in base al numero di chiamate API. In questo scenario, se il ritardo tra l’evento di modifica nell’applicazione proprietaria e la propagazione all’applicazione in uso è negoziabile, è prassi comune raggruppare i messaggi correlati in singole chiamate API. Questo è un altro scenario in cui la modalità di notifica semplifica l’intero sistema. Nella modalità di trasferimento dello stato, più messaggi devono essere confrontati per il loro contenuto prima che ciò possa essere ottenuto. La complessità aumenta in modo significativo se la modalità snapshot non viene scelta dal provider.

Semplicità del produttore di eventi:

La complessità a cui devono essere soggetti i produttori di eventi è un criterio chiave per la scelta del modello di progettazione. Come si vede negli esempi, più l’evento diventa verboso, più è complesso estrarre i dati e più costoso è inviarlo via cavo. Questo, a sua volta, causa maggiori rischi nell’invio di eventi fuori servizio. Inoltre, quando i dati iniziano a comparire nel messaggio stesso, inizia a entrare in gioco la necessità di proteggere i canali e le piattaforme di messaggistica (comprese le esigenze di crittografia / mascheramento, ecc.). Anche il controllo dell’accesso deve essere applicato alla piattaforma dell’evento con la stessa diligenza dell’API di lettura.

Necessità di monitorare tutte le modifiche di stato:

Se esiste un requisito in base al quale un consumatore a valle deve conoscere ogni cambiamento di stato a cui è stato sottoposto il proprietario dei dati, i precedenti punti di decisione vengono effettivamente ignorati. Sebbene non mi piaccia particolarmente l’idea che i sistemi esterni controllino ogni cambiamento, potrebbero esserci ragioni specifiche all’interno dell’organizzazione per giustificarlo. Idealmente, in un ecosistema adeguatamente suddiviso, la responsabilità dell’audit di un’entità dovrebbe rientrare nello stesso servizio che ha inviato l’evento in primo luogo (e dovrebbe essere un’unica fonte di verità per tale audit). Invece, i sistemi che consumano dovrebbero essere in grado di accettare una replica eventualmente coerente della fonte della verità: il proprietario dei dati dell’entità. Questo è probabilmente un dibattito in sé da avere. Tuttavia, per l’argomento in questione, questo requisito di un sistema che controllerà tutti i cambiamenti di stato esternamente non ha altra scelta che gestire correttamente la consegna fuori ordine e lascerà il trasferimento di stato trasportato dall’evento come l’unica opzione da scegliere.

Conclusione

Il modello di notifica degli eventi è semplice da definire e implementare dal punto di vista del produttore e del consumatore di eventi. Dal punto di vista del consumatore, è necessario effettuare una chiamata API aggiuntiva (questa attività in sé è tanto semplice quanto sembra) esiste una condizione di errore da gestire: l’endpoint per recuperare lo stato corrente dei dati non risponde. Tuttavia, considererei questa complessità più facile da affrontare rispetto alla gestione della consegna fuori ordine e all’introspezione di più parti dell’applicazione di consumo e al confronto con l’evento in arrivo per prendere decisioni di consumo.

Se i requisiti tuttavia escludono la modalità di notifica dall’equazione, tieni presente le seguenti strategie per raggiungere questo obiettivo:

PS:

Un paio di cose in cui questo post non ha approfondito:

Evento vs. comando:

Approvvigionamento eventi e CQRS:

Questo post non è entrato in un altro argomento chiave, Event Sourcing (e il suo partner, CQRS) poiché quel modello ha meno a che fare con la comunicazione tra processi e più con il modo in cui un dato sistema sceglie di mantenere il proprio stato. Un argomento per un altro giorno forse.