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.
La gestione degli errori, la progettazione per l'idempotenza e la gestione del comportamento di ripetizione dei tentativi sono alcune delle misure critiche che è possibile adottare per garantire che le funzioni attivate da Hub eventi di Azure siano resilienti e in grado di gestire grandi volumi di dati. Questo articolo illustra questi concetti cruciali e fornisce raccomandazioni per soluzioni di streaming di eventi serverless.
Azure offre tre principali servizi di messaggistica che è possibile usare con Funzioni di Azure per supportare un'ampia gamma di scenari univoci basati su eventi. A causa del modello consumer partizionato e della possibilità di inserire dati a una frequenza elevata, Hub eventi viene comunemente usato per scenari di streaming di eventi e Big Data. Per un confronto dettagliato dei servizi di messaggistica Azure, vedere Scegliere tra Griglia di eventi, Hub eventi e bus di servizio di Azure.
Vantaggi e sfide per lo streaming
Comprendere i vantaggi e gli svantaggi dei flussi consente di apprezzare il funzionamento di un servizio come Hub eventi. Questo contesto è necessario anche quando si effettuano decisioni significative sull'architettura, si risolvono i problemi e si ottimizzano le prestazioni. Considerare i concetti chiave seguenti sulle soluzioni che usano sia Hub eventi che Funzioni:
I flussi non sono code: Event Hubs, Kafka e altre offerte simili basate sul modello consumer partizionato non supportano intrinsecamente alcune delle funzionalità principali in un broker di messaggi come il bus di servizio. Forse l’indizio più evidente di queste differenze è il fatto che le operazioni di lettura sono non distruttive. Questo comportamento garantisce che i dati letti dall'host di Funzioni rimangano disponibili in un secondo momento. I messaggi non sono modificabili e rimangono per consentire ad altri consumer di leggere, incluso potenzialmente lo stesso consumer che lo legge nuovamente. Per questo motivo, le soluzioni che implementano modelli come Competing Consumers potrebbero essere meglio servite con un broker di messaggi, come il bus di servizio.
Mancanza di supporto intrinseco per i messaggi non recapitabili: Un canale di messaggi non recapitabili non è una funzionalità nativa in Event Hubs o Kafka. Spesso, il concetto di messaggi non recapitabili è integrato in una soluzione di streaming per tenere conto dei dati che non possono essere elaborati. Questa funzionalità non è intenzionalmente un elemento innato in Hub eventi e viene aggiunta solo sul lato consumer per produrre un comportamento o un effetto simile. Se hai bisogno del supporto per le code dei messaggi non recapitabili, potresti voler rivedere la tua scelta di un servizio di messaggistica in streaming.
Un'unità di lavoro è una partizione: in un broker di messaggi tradizionale, un'unità di lavoro è un singolo messaggio. In una soluzione di streaming, una partizione viene spesso considerata l'unità di lavoro. Se ogni evento in un hub eventi viene considerato come un messaggio distinto che richiede l'elaborazione degli ordini o la gestione delle transazioni finanziarie, è possibile esplorare un servizio di messaggistica più adatto per prestazioni o elaborazione ottimali.
Nessun filtro sul lato server: Uno dei motivi per cui Hub eventi è in grado di aumentare notevolmente la scalabilità e la velocità effettiva è il basso sovraccarico del servizio stesso. Le funzionalità come il filtro lato server, gli indici e il coordinamento tra broker non fanno parte dell'architettura di Hub eventi. Le funzioni vengono usate occasionalmente per filtrare gli eventi instradandoli ad altri hub eventi in base al contenuto nel corpo o nell'intestazione. Questo approccio è comune nel stream di eventi, con l'avvertenza che la funzione iniziale legge e valuta ogni evento.
Ogni lettore deve leggere tutti i dati: Poiché il filtro lato server non è disponibile, un consumer legge in sequenza tutti i dati in una partizione. Legge i dati che potrebbero non essere rilevanti o che potrebbero essere in formato non valido. È possibile usare diverse strategie per compensare queste sfide.
Queste decisioni di progettazione consentono a Event Hub di supportare un flusso significativo di eventi e fornire ai consumatori un servizio resiliente per la lettura. Ogni applicazione consumer è responsabile del mantenimento dei propri offset lato client o di un cursore per tali eventi. Il basso sovraccarico rende Hub eventi un'opzione conveniente per lo streaming di eventi.
Idempotenza
Uno dei principi fondamentali di Event Hubs è il concetto di consegna almeno una volta. Questo approccio garantisce che gli eventi vengano sempre consegnati. Significa anche che gli eventi possono essere ricevuti più volte, anche ripetutamente, dai consumer come una funzione. Per questo motivo, una funzione attivata da un Hub eventi deve supportare il modello Consumer idempotente.
Partire dal presupposto di una consegna almeno una volta, in particolare nel contesto di un'architettura basata su eventi, rappresenta un approccio responsabile per elaborare gli eventi in modo affidabile. La funzione deve essere idempotente in modo che il risultato dell'elaborazione dello stesso evento più volte sia uguale all'elaborazione una sola volta.
Eventi duplicati
Diversi scenari possono comportare la consegna di eventi duplicati a una funzione:
Checkpointing: Se l'host di Funzioni di Azure va in crash o la soglia impostata per la frequenza del checkpoint batch non viene soddisfatta, non viene creato un checkpoint. Di conseguenza, l'offset del consumer non viene avanzato e, la volta successiva in cui la funzione viene richiamata, riprende dall'ultimo checkpoint. Il checkpoint si verifica a livello di partizione per ogni consumer.
Eventi duplicati pubblicati: Molte tecniche possono ridurre le probabilità che lo stesso evento venga pubblicato in un flusso, ma il consumatore deve comunque gestire i duplicati in maniera idempotente.
Riconoscimenti mancanti: In alcune situazioni, una richiesta in uscita a un servizio ha esito positivo, ma non viene mai ricevuto un riconoscimento (ACK) dal servizio. Questo scenario potrebbe indurre a credere che la chiamata in uscita sia fallita e portare ad avviare una serie di nuovi tentativi o altri comportamenti della funzione. Alla fine, è possibile pubblicare eventi duplicati o non creare un checkpoint.
Tecniche di deduplicazione
Progettare le funzioni per gestire l'input identico per impostazione predefinita quando si usa l'associazione di trigger di Hub eventi. Considerare le tecniche seguenti:
Cercare duplicati: Prima dell'elaborazione, eseguire i passaggi necessari per verificare che l'evento debba essere elaborato. In alcuni casi, è necessario esaminare per verificare che l'evento sia ancora valido. È anche possibile che la gestione dell'evento non sia più necessaria a causa dell'aggiornamento dei dati o della logica che invalida l'evento.
Progettare eventi per idempotenza: È possibile assicurarsi che l'elaborazione di un evento più volte non abbia effetti negativi includendo informazioni aggiuntive nel payload dell'evento. Si consideri l'esempio di un evento che include un importo da ritirare da un conto bancario. Se il prelievo non viene gestito in modo responsabile, il saldo del conto potrebbe essere decrementato più volte. Tuttavia, se l'evento contiene il saldo aggiornato del conto, il saldo può essere utilizzato per eseguire un'operazione di upsert sul saldo del conto bancario. Questo approccio di trasferimento dello stato veicolato dagli eventi richiede occasionalmente il coordinamento tra produttori e consumatori. Usarlo quando ha senso per i servizi partecipanti.
Gestione degli errori e tentativi
La gestione degli errori e i tentativi sono due delle qualità più importanti delle applicazioni distribuite, guidate dagli eventi e le funzioni non fanno eccezione. Per le soluzioni di streaming degli eventi, il supporto appropriato per la gestione degli errori è fondamentale perché migliaia di eventi possono trasformarsi rapidamente in un numero uguale di errori se non vengono gestiti correttamente.
Indicazioni sulla gestione degli errori
Senza la gestione degli errori, può essere difficile implementare nuovi tentativi, rilevare le eccezioni di runtime e analizzare i problemi. Ogni funzione deve avere almeno un livello di gestione degli errori. Seguire queste linee guida consigliate:
Usare Application Insights: abilitare e usare Application Insights per registrare gli errori e monitorare l'integrità delle funzioni. Tenere presente le opzioni di campionamento configurabili per gli scenari che elaborano un volume elevato di eventi.
Aggiungere la gestione degli errori strutturati: Usare i costrutti di gestione degli errori appropriati per ogni linguaggio di programmazione per rilevare, registrare e rilevare le eccezioni previste e non gestite nel codice della funzione. Ad esempio, usa un blocco try-catch in C#, Java e JavaScript e i blocchi try ed except in Python per gestire le eccezioni.
Implementare la registrazione: L'intercettazione di un'eccezione durante l'esecuzione offre la possibilità di registrare informazioni critiche che è possibile usare per rilevare, riprodurre e risolvere i problemi in modo affidabile. Registrare nel log l'eccezione, non solo il messaggio, ma anche il contenuto, l'eccezione interna e altri artefatti che possano essere utili in seguito.
Non intercettare e ignorare le eccezioni: Una delle cose peggiori che è possibile fare è intercettare un'eccezione e fare nulla con esso. Se si rileva un'eccezione generica, registrarla da qualche parte. Se non si registrano errori, è difficile analizzare i bug e segnalare i problemi.
Nuovi tentativi
L'implementazione della logica di ripetizione dei tentativi in un'architettura di streaming di eventi può essere complessa. Il supporto dei token di cancellazione, del numero di tentativi e delle strategie di backoff esponenziale sono solo alcuni degli aspetti che rendono tutto ciò complesso. Fortunatamente, Funzioni fornisce criteri di ripetizione dei tentativi per molte di queste attività che in genere si codificano manualmente. Per indicazioni generali sulle strategie di ripetizione dei tentativi, vedere Raccomandazioni per la gestione degli errori temporanei.
Considerare i fattori seguenti quando si usano i criteri di ripetizione con il binding di Event Hubs:
Evitare tentativi illimitati: Quando si imposta l'impostazione numero massimo di tentativi su -1, la funzione ritenta per un periodo illimitato. In generale, usare i tentativi indefiniti con Funzioni con parsimonia e quasi mai con il binding del trigger di Hub eventi.
Scegliere la strategia di ripetizione dei tentativi appropriata: Una strategia di ritardo fisso potrebbe essere ottimale per gli scenari che ricevono un *back pressure* da parte di altri servizi di Azure. In questi casi, il ritardo può aiutare a evitare la strozzatura e altre limitazioni rilevate da tali servizi. La strategia di backoff esponenziale offre maggiore flessibilità per gli intervalli di ritardo per i tentativi ed è comunemente usata nelle integrazioni con servizi non Microsoft, endpoint REST e altri servizi Azure.
Mantieni bassi gli intervalli e il numero di tentativi: Quando possibile, mantieni un intervallo tra i tentativi inferiore a un minuto. Inoltre, mantenere il numero massimo di tentativi a un numero ragionevolmente basso. Queste impostazioni sono particolarmente pertinenti quando si usa il piano a consumo di funzioni.
Usa il pattern Circuit Breaker: Un errore temporaneo può verificarsi di tanto in tanto ed è un caso d'uso naturale per i nuovi tentativi. Tuttavia, se si verifica un numero significativo di errori o problemi durante l'elaborazione della funzione, potrebbe essere opportuno arrestare la funzione, risolvere i problemi e riavviarlo in un secondo momento.
Un punto importante sulla funzionalità dei criteri di ripetizione dei tentativi in Funzioni è che si tratta di una funzionalità ottimale per la rielaborazione degli eventi. Non sostituisce la necessità di gestire gli errori, registrare e altri modelli importanti che forniscono resilienza al codice.
Strategie per errori e dati danneggiati
Diversi approcci importanti consentono di compensare i problemi che si verificano a causa di errori o dati errati in un flusso di eventi. Considerare le strategie fondamentali seguenti:
Interrompere l'invio e la lettura di eventi: Per risolvere il problema sottostante, sospendere la lettura e la scrittura di eventi. Il vantaggio di questo approccio è che i dati non vengono persi e le operazioni possono riprendere dopo l'implementazione di una correzione. Questo approccio potrebbe richiedere un componente interruttore nell'architettura ed eventualmente una notifica ai servizi interessati per ottenere una pausa. In alcuni casi, l'arresto di una funzione potrebbe essere necessario fino a quando non vengono risolti i problemi.
Eliminare i messaggi: Se i messaggi non sono importanti o cruciali, è consigliabile eliminarli anziché elaborarli. Questo approccio non funziona per gli scenari che richiedono coerenza assoluta, ad esempio la registrazione degli spostamenti in una partita di scacchi o transazioni basate su finanza. È consigliabile implementare la gestione degli errori all'interno di una funzione per rilevare ed eliminare messaggi che non possono essere elaborati.
Eventi di nuovo tentativo: In molte situazioni può essere necessaria la rielaborazione di un evento. Lo scenario più comune è un errore temporaneo rilevato quando viene chiamato un altro servizio o una dipendenza. Gli errori di rete, i limiti del servizio e la disponibilità e la coerenza assoluta sono probabilmente i casi d'uso più frequenti che giustificano i tentativi di rielaborazione.
Usare un flusso di messaggi non recapitabili: L'obiettivo è pubblicare l'evento in un hub eventi diverso in modo che il flusso esistente non venga interrotto. L'evento si sposta dal percorso critico e può essere gestito in un secondo momento o da un processo diverso. Questa soluzione viene usata di frequente per la gestione di messaggi o eventi non elaborabili. Ogni funzione configurata con un consumer group diverso si imbatterà comunque in dati errati o corrotti nel proprio flusso e dovrà gestirli in modo responsabile.
Usa retry e dead letter: Questo metodo combina numerosi tentativi di retry con la pubblicazione finale in uno stream dead letter una volta raggiunta una soglia.
Usare un registro schemi: È possibile usare un registro schemi come strumento proattivo per migliorare la coerenza e la qualità dei dati. Azure Registro schemi supporta la transizione degli schemi insieme al controllo delle versioni e alle diverse modalità di compatibilità man mano che gli schemi si evolvono. Al suo interno, lo schema funge da contratto tra producer e consumer. Può ridurre la possibilità che vengano pubblicati nel flusso di dati dati non validi o danneggiati.
Non c'è una soluzione perfetta. È necessario esaminare attentamente le conseguenze e i compromessi di ogni strategia. A seconda dei requisiti, l'approccio migliore potrebbe essere quello di usare insieme diverse di queste tecniche.
Collaboratori
Microsoft gestisce questo articolo. I seguenti collaboratori hanno scritto questo articolo.
Autore principale:
- David Barkol | GBB per le app di intelligenza artificiale
Per visualizzare i profili LinkedIn non pubblici, accedere a LinkedIn.
Passaggi successivi
Prima di continuare, prendere in considerazione la revisione di questi articoli correlati: