Strategie di gestione degli errori parziali
Suggerimento
Questo contenuto è un estratto dell'eBook "Microservizi .NET: Architettura per le applicazioni .NET incluse in contenitori", disponibile in .NET Docs o come PDF scaricabile gratuitamente e da poter leggere offline.
Per gestire gli errori parziali, usare una delle strategie descritte qui.
Usare la comunicazione asincrona, ad esempio la comunicazione basata su messaggi, tra i microservizi interni. È consigliabile evitare di creare lunghe catene di chiamate HTTP sincrone tra i microservizi interni, perché questa configurazione non corretta finirà per diventare la causa principale di interruzioni di servizio prolungate. Al contrario è consigliabile usare solo la comunicazione asincrona (basata su messaggi) tra i microservizi interni dopo il ciclo di richiesta/risposta iniziale, salvo per le comunicazioni front-end tra le applicazioni client e il primo livello dei microservizi o i gateway API con granularità fine. Le architetture di coerenza finale e basate su eventi consentiranno di ridurre al minimo l'effetto domino. Questi approcci impongono un livello di autonomia dei microservizi più elevato e consentono di prevenire il problema specificato.
Usare i tentativi con backoff incrementale. Questa tecnica permette di evitare errori brevi e intermittenti tramite la ripetizione delle chiamate per un determinato numero di volte, nel caso in cui il servizio non sia stato disponibile per un breve periodo di tempo. Questa situazione può essere causata da problemi di rete intermittenti o quando un microservizio/contenitore viene spostato in un altro nodo del cluster. Tuttavia, se i tentativi non sono progettati correttamente con interruttori di circuito, l'effetto domino può aggravarsi fino a generare un errore di tipo Denial of Service (DoS).
Usare i timeout di rete. In generale, i client devono essere progettati in modo da non bloccarsi a tempo indefinito e per usare sempre i timeout durante l'attesa per una risposta. L'uso dei timeout garantisce che le risorse non rimangano bloccate per un periodo di tempo indefinito.
Usare lo schema Circuit Breaker. Con questo approccio, il processo client tiene traccia del numero di richieste non riuscite. Se la frequenza di errori supera un limite configurato, si attiva un "interruttore di circuito" affinché i tentativi successivi abbiano immediatamente esito negativo. Se un numero elevato di richieste presenta errori, il servizio potrebbe non essere disponibile e risulta inutile inviare altre richieste. Trascorso il periodo di timeout, il client deve riprovare e, se le nuove richieste hanno esito positivo, l'interruttore di circuito si chiude.
Fornire fallback. Con questo approccio, il processo client esegue la logica di fallback in caso di esito negativo di una richiesta, ad esempio restituendo i dati memorizzati nella cache o un valore predefinito. Questo approccio è adatto alle query, ma risulta più complesso per gli aggiornamenti o i comandi.
Limitare il numero di richieste in coda. I client devono inoltre imporre una soglia massima per il numero di richieste in sospeso che un microservizio può inviare a un determinato servizio. Se il limite è stato raggiunto, è in genere inutile inviare richieste aggiuntive e questi tentativi avranno immediatamente esito negativo. In termini di implementazione, è possibile usare i criteri Bulkhead Isolation (isolamento a scomparti) in Polly per soddisfare questo requisito. Questo approccio rappresenta semplicemente una limitazione della parallelizzazione con SemaphoreSlim come implementazione. Consente anche la creazione di una "coda" all'esterno dello scomparto. È possibile rimuovere il carico in eccesso anche prima dell'esecuzione, ad esempio se la capacità è considerata piena. La risposta a determinati scenari di errori risulta quindi più veloce rispetto a quella di un interruttore di circuito, dal momento che l'interruttore rimane in attesa degli errori. L'oggetto BulkheadPolicy in Polly visualizza il livello di riempimento dello scomparto e della coda, offre eventi di overflow e può anche essere usato per aumentare automaticamente il numero di istanze.
Risorse aggiuntive
Modelli di resilienza
https://learn.microsoft.com/azure/architecture/framework/resiliency/reliability-patternsAggiunta di resilienza e ottimizzazione delle prestazioni
https://learn.microsoft.com/previous-versions/msp-n-p/jj591574(v=pandp.10)Bulkhead. Repository GitHub. Implementazione con i criteri Polly.
https://github.com/App-vNext/Polly/wiki/BulkheadProgettazione di applicazioni resilienti per Azure
https://learn.microsoft.com/azure/architecture/framework/resiliency/app-designGestione degli errori temporanei
https://learn.microsoft.com/azure/architecture/best-practices/transient-faults