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.
Un'architettura basata su eventi è costituita da producer di eventi che generano un flusso di eventi, consumer di eventi in ascolto di questi eventi e canali di eventi (spesso implementati come broker eventi o servizi di inserimento) che trasferiscono eventi dai producer ai consumer.
Architecture
Gli eventi vengono recapitati quasi in tempo reale, in modo che i consumer possano rispondere immediatamente agli eventi che si verificano. I produttori sono separati dai consumer, il che significa che un produttore non sa quali consumer sono in ascolto. I consumer vengono anche separati l'uno dall'altro e ogni consumer vede tutti gli eventi.
Questo processo differisce da un modello Consumer concorrenti. Nel modello Consumer concorrenti i consumer estraggono i messaggi da una coda. Ogni messaggio viene elaborato una sola volta, presupponendo che non siano presenti errori. In alcuni sistemi, ad esempio Azure IoT, gli eventi devono essere inseriti in volumi elevati.
Un'architettura basata su eventi può usare un modello di pubblicazione-sottoscrizione o un modello di flusso di eventi.
Pubblicazione-sottoscrizione: L'infrastruttura di messaggistica publish-subscribe tiene traccia delle sottoscrizioni. Quando viene pubblicato un evento, invia l'evento a ogni sottoscrittore. Dopo aver recapitato l'evento, non può essere riprodotto e i nuovi sottoscrittori non visualizzano l'evento. È consigliabile usare Griglia di eventi di Azure per scenari di pubblicazione-sottoscrizione.
Streaming di eventi: Gli eventi vengono scritti in un log. Gli eventi vengono ordinati rigorosamente all'interno di una partizione e sono durevoli. I client non sottoscrivono il flusso. Un client può invece leggere da qualsiasi parte del flusso. Il client è responsabile dell'avanzamento della posizione nel flusso, il che significa che un client può partecipare in qualsiasi momento e può riprodurre eventi. Hub eventi di Azure è progettato per lo streaming di eventi a velocità effettiva elevata.
Sul lato consumer esistono alcune varianti comuni:
Elaborazione semplice di eventi: Un evento attiva immediatamente un'azione nel consumer. Ad esempio, è possibile usare Funzioni di Azure con un trigger di Griglia di eventi o un trigger del bus di servizio di Azure in modo che il codice venga eseguito quando viene pubblicato un messaggio.
Correlazione di eventi di base: Un consumer elabora alcuni eventi aziendali discreti, li correla in base a un identificatore e rende persistenti le informazioni degli eventi precedenti da usare quando elabora eventi successivi. Le librerie come NServiceBus e MassTransit supportano questo modello.
Elaborazione di eventi complessi: Un consumer usa una tecnologia come Analisi di flusso di Azure per analizzare una serie di eventi e identificare i modelli nei dati degli eventi. Ad esempio, è possibile aggregare le letture da un dispositivo incorporato in un intervallo di tempo e generare una notifica se la media mobile supera una soglia specifica.
Elaborazione del flusso di eventi: Usare una piattaforma di streaming dei dati, ad esempio Hub IoT di Azure, Hub eventi o Hub eventi per Apache Kafka, come pipeline per inserire gli eventi e inviarli ai processori di flusso. I processori di flusso agiscono per elaborare o trasformare il flusso. Potrebbero essere presenti più processori di flusso per sottosistemi diversi dell'applicazione. Questo approccio è particolarmente adatto per i carichi di lavoro IoT.
L'origine degli eventi potrebbe essere esterna al sistema, ad esempio i dispositivi fisici in una soluzione IoT. In tal caso, il sistema deve essere in grado di inserire i dati in corrispondenza del volume e della velocità effettiva richiesti dall'origine dati.
Esistono due approcci principali per strutturare i payload degli eventi. Quando si ha il controllo sui consumer di eventi, è possibile decidere la struttura del payload per ogni consumer. Questa strategia consente di combinare approcci in base alle esigenze all'interno di un singolo carico di lavoro.
Includere tutti gli attributi obbligatori nel payload: Usare questo approccio quando si desidera che i consumer dispongano di tutte le informazioni disponibili senza dover eseguire query su un'origine dati esterna. Tuttavia, può causare problemi di coerenza dei dati a causa di più sistemi di record, soprattutto dopo gli aggiornamenti. La gestione dei contratti e il controllo delle versioni possono anche diventare complessi.
Includere solo le chiavi nel payload: In questo approccio, i consumer recuperano gli attributi necessari, ad esempio una chiave primaria, per recuperare in modo indipendente i dati rimanenti da un'origine dati. Questo metodo offre una migliore coerenza dei dati perché ha un singolo sistema di record. Tuttavia, può comportare prestazioni inferiori rispetto al primo approccio perché i consumer devono eseguire spesso query sull'origine dati. Per quanto riguarda l'accoppiamento, la larghezza di banda, la gestione dei contratti o il controllo delle versioni, si hanno meno preoccupazioni perché gli eventi più piccoli e i contratti più semplici riducono la complessità.
Nel diagramma precedente ogni tipo di consumer viene visualizzato come una singola casella. Per evitare che il consumer diventi un singolo punto di guasto nel sistema, è tipico avere più istanze di un consumer. Potrebbero essere necessarie più istanze anche per gestire il volume e la frequenza degli eventi. Un singolo consumer può elaborare eventi su più thread. Questa configurazione può creare problemi se gli eventi devono essere elaborati in ordine o richiedono una semantica di una sola volta. Per altre informazioni, vedere Ridurre al minimo il coordinamento.
Esistono due topologie primarie all'interno di molte architetture guidate dagli eventi:
Topologia broker: I componenti trasmettono eventi all'intero sistema. Altri componenti agiscono sull'evento o ignorano l'evento. Questa topologia è utile quando il flusso di elaborazione degli eventi è relativamente semplice. Non esiste un coordinamento centrale o un'orchestrazione, quindi questa topologia può essere dinamica.
Questa topologia è altamente disaccoppiata, che consente di garantire scalabilità, velocità di risposta e tolleranza di errore dei componenti. Nessun componente è proprietario o è a conoscenza dello stato di qualsiasi transazione aziendale a più passaggi e le azioni vengono eseguite in modo asincrono. Di conseguenza, le transazioni distribuite sono rischiose perché non esiste alcun meccanismo predefinito per il riavvio o la riproduzione. È necessario considerare attentamente la gestione degli errori e le strategie di intervento manuale perché questa topologia può essere un'origine di incoerenza dei dati.
Topologia mediator: Questa topologia risolve alcune delle carenze della topologia broker. Esiste un mediator di eventi che gestisce e controlla il flusso degli eventi. Il mediatore eventi gestisce lo stato e gestisce le funzionalità di gestione e riavvio degli errori. A differenza della topologia broker, i componenti della topologia mediator trasmettono le occorrenze come comandi e solo ai canali designati. Questi canali sono spesso code di messaggi. È previsto che i consumer eselaborino questi comandi.
Questa topologia offre un maggiore controllo, una migliore gestione degli errori distribuiti e una coerenza dei dati potenzialmente migliore. Tuttavia, questa topologia introduce un maggiore accoppiamento tra i componenti e il mediatore dell'evento può diventare un collo di bottiglia o un problema di affidabilità.
Quando usare questa architettura
È consigliabile usare questa architettura quando si verificano le condizioni seguenti:
Più sottosistemi devono elaborare gli stessi eventi.
È necessaria l'elaborazione in tempo reale con ritardo di tempo minimo.
È necessaria un'elaborazione complessa degli eventi, ad esempio criteri di ricerca o aggregazione nel tempo.
È necessario un volume elevato e una velocità elevata dei dati, ad esempio con IoT.
È necessario separare produttori e consumer per obiettivi di scalabilità e affidabilità indipendenti.
Vantaggi
Questa architettura offre i vantaggi seguenti:
- I produttori e i consumer sono disaccoppiati.
- Non sono presenti integrazioni da punto a punto. È facile aggiungere nuovi consumer al sistema.
- I consumer possono rispondere immediatamente agli eventi quando si verificano.
- È altamente scalabile, elastico e distribuito.
- I sottosistemi hanno visualizzazioni indipendenti del flusso di eventi.
Problematiche
Recapito garantito
In alcuni sistemi, in particolare negli scenari IoT, è fondamentale garantire che gli eventi vengano recapitati.
Elaborazione di eventi in ordine o una sola volta
Per resilienza e scalabilità, ogni tipo di consumer viene in genere eseguito in più istanze. Questo processo può creare una richiesta di verifica se gli eventi devono essere elaborati in ordine all'interno di un tipo di consumer o se la logica di elaborazione dei messaggi idempotenti non è implementata.
Coordinamento dei messaggi tra i servizi
I processi aziendali hanno spesso più servizi che pubblicano e sottoscrivono i messaggi per ottenere un risultato coerente in un intero carico di lavoro. È possibile usare modelli di flusso di lavoro come Coreografia e Saga Orchestration per gestire in modo affidabile i flussi di messaggi tra vari servizi.
Gestione degli errori
L'architettura basata su eventi si basa principalmente sulla comunicazione asincrona. Una sfida comune che presenta la comunicazione asincrona è la gestione degli errori. Un modo per risolvere questo problema consiste nell'usare un processore del gestore errori dedicato.
Quando un consumer di eventi rileva un errore, invia immediatamente e in modo asincrono l'evento problematico al processore del gestore errori e continua l'elaborazione di altri eventi. Il processore del gestore errori tenta di risolvere il problema. Se ha esito positivo, il processore del gestore errori invia nuovamente l'evento al canale di inserimento originale. In caso di errore, il processore può inoltrare l'evento a un amministratore per un'ulteriore ispezione. Quando si usa un processore del gestore errori, gli eventi inviati di nuovo vengono elaborati fuori sequenza.
Perdita di dati
Un'altra sfida che presenta la comunicazione asincrona è la perdita di dati. Se uno dei componenti si arresta in modo anomalo prima di elaborare correttamente e consegnare l'evento al componente successivo, l'evento viene eliminato e non raggiunge mai la destinazione finale. Per ridurre al minimo la probabilità di perdita di dati, rendere persistenti gli eventi in transito e rimuovere o annullare la coda degli eventi solo quando il componente successivo riconosce la ricezione dell'evento. Queste funzionalità sono note come modalità di riconoscimento client e supporto dell'ultimo partecipante.
Implementazione di un modello tradizionale di richiesta-risposta
A volte il producer di eventi richiede una risposta immediata da parte del consumer di eventi, ad esempio per ottenere l'idoneità del cliente prima di procedere con un ordine. In un'architettura basata su eventi, è possibile ottenere comunicazioni sincrone usando la messaggistica di richiesta-risposta.
Questo modello viene implementato con una coda di richieste e una coda di risposte. Il producer di eventi invia una richiesta asincrona a una coda di richieste, sospende altre operazioni su tale attività e attende una risposta nella coda di risposta. Questo approccio trasforma questo modello in modo efficace in un processo sincrono. I consumer di eventi elaborano quindi la richiesta e inviano la risposta tramite una coda di risposta. Questo approccio usa in genere un ID sessione per il rilevamento, quindi il producer di eventi sa quale messaggio nella coda di risposta è correlato alla richiesta specifica. La richiesta originale può anche specificare il nome della coda di risposta, potenzialmente temporanea, in un'intestazione reply-to o un altro attributo personalizzato concordato a vicenda.
Manutenzione del numero appropriato di eventi
La generazione di un numero eccessivo di eventi con granularità fine può saturare e sovraccaricare il sistema. Un volume eccessivo di eventi rende difficile analizzare efficacemente il flusso complessivo degli eventi. Questo problema è esacerbato quando è necessario eseguire il rollback delle modifiche. Al contrario, il consolidamento eccessivo degli eventi può anche creare problemi, che comportano l'elaborazione e le risposte non necessarie da parte dei consumer di eventi.
Per ottenere il giusto equilibrio, prendere in considerazione le conseguenze degli eventi e se i consumer devono esaminare i payload dell'evento per determinare le risposte. Ad esempio, se si dispone di un componente di controllo della conformità, potrebbe essere sufficiente pubblicare solo due tipi di eventi: conforme e non conforme. Questo approccio consente di garantire che ogni evento venga elaborato solo dai consumer pertinenti, che impedisce l'elaborazione non necessaria.
Altre considerazioni
La quantità di dati da includere in un evento può essere una considerazione significativa che influisce sulle prestazioni e sui costi. È possibile semplificare il codice di elaborazione ed eliminare ricerche aggiuntive inserendo tutte le informazioni pertinenti necessarie per l'elaborazione direttamente nell'evento. Quando si aggiunge solo una quantità minima di informazioni a un evento, ad esempio alcuni identificatori, si riducono i tempi di trasporto e i costi. Tuttavia, questo approccio richiede al codice di elaborazione di recuperare eventuali informazioni aggiuntive necessarie. Per altre informazioni, vedi Mettere gli eventi su una dieta.
Una richiesta è visibile solo al componente di gestione delle richieste. Tuttavia, gli eventi sono spesso visibili a più componenti in un carico di lavoro, anche se tali componenti non li usano o non sono destinati a utilizzarli. Per operare con una mentalità "presupporre la violazione", tenere presente quali informazioni includere negli eventi per evitare l'esposizione imprevista delle informazioni.
Molte applicazioni usano l'architettura basata su eventi come architettura primaria. È possibile combinare questo approccio con altri stili architetturali per creare un'architettura ibrida. Le combinazioni tipiche includono microservizi e pipe e filtri. Integrare un'architettura guidata dagli eventi per migliorare le prestazioni del sistema eliminando i colli di bottiglia e fornendo una pressione indietro durante volumi di richieste elevate.
Domini specifici spesso si estendono su più producer di eventi, consumer o canali di eventi. Le modifiche apportate a un dominio specifico potrebbero influire su molti componenti.