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.
Suggerimento
Questo contenuto è un estratto dell'eBook, Architettura di microservizi .NET per applicazioni .NET containerizzati, disponibile in documentazione .NET o come PDF scaricabile gratuitamente leggibile offline.
Nei sistemi distribuiti come le applicazioni basate su microservizi esiste un rischio sempre presente di errore parziale. Ad esempio, un singolo microservizio/contenitore può non riuscire o non essere disponibile per rispondere per un breve periodo di tempo oppure un'unica macchina virtuale o un singolo server può arrestarsi in modo anomalo. Poiché i client e i servizi sono processi separati, un servizio potrebbe non essere in grado di rispondere in modo tempestivo alla richiesta di un client. Il servizio potrebbe essere sovraccarico e rispondere molto lentamente alle richieste o potrebbe semplicemente non essere accessibile per un breve periodo di tempo a causa di problemi di rete.
Si consideri ad esempio la pagina Dettagli ordine dell'applicazione di esempio eShopOnContainers. Se il microservizio di ordinamento non risponde quando l'utente tenta di inviare un ordine, un'implementazione non valida del processo client (l'applicazione Web MVC), ad esempio se il codice client dovesse usare RPC sincrone senza timeout, blocca i thread in attesa illimitata di una risposta. Oltre a creare un'esperienza utente negativa, ogni attesa non reattiva consuma o blocca un thread, e i thread sono estremamente preziosi nelle applicazioni altamente scalabili. Se sono presenti molti thread bloccati, alla fine il runtime dell'applicazione può esaurirsi di thread. In tal caso, l'applicazione può diventare non rispondente a livello globale anziché semplicemente parzialmente non rispondente, come illustrato nella figura 8-1.
Figura 8-1. Errori parziali a causa di dipendenze che influiscono sulla disponibilità del thread di servizio.
In un'applicazione estesa basata su microservizi, qualsiasi errore parziale può essere amplificato, soprattutto se la maggior parte delle interazioni tra microservizi interni è basata su chiamate HTTP sincrone (considerate un anti-pattern). Si pensi a un sistema che riceve milioni di chiamate in arrivo al giorno. Se il sistema ha una progettazione non valida basata su lunghe catene di chiamate HTTP sincrone, queste chiamate in ingresso potrebbero comportare molte più milioni di chiamate in uscita (si supponga che un rapporto di 1:4) a decine di microservizi interni come dipendenze sincrone. Questa situazione è illustrata nella figura 8-2, in particolare la dipendenza n. 3, che avvia una catena, chiamando la dipendenza n. 4, che chiama quindi #5.
Figura 8-2. L'impatto di una progettazione non corretta con catene lunghe di richieste HTTP
L'errore intermittente è garantito in un sistema distribuito e basato sul cloud, anche se ogni dipendenza ha una disponibilità eccellente. È un fatto che devi considerare.
Se non si progettano e implementano tecniche per garantire la tolleranza di errore, è possibile amplificare anche piccoli tempi di inattività. Ad esempio, 50 dipendenze ognuna con 99,99% di disponibilità genererebbe diverse ore di inattività ogni mese a causa di questo effetto increspante. Quando una dipendenza di microservizi non riesce durante la gestione di un volume elevato di richieste, tale errore può saturare rapidamente tutti i thread di richiesta disponibili in ogni servizio e arrestare l'intera applicazione.
Figura 8-3. Errore parziale amplificato da microservizi con catene lunghe di chiamate HTTP sincrone
Per ridurre al minimo questo problema, nella sezione Integrazione asincrona di microservizi applicare l'autonomia del microservizio, questa guida invita a usare la comunicazione asincrona tra i microservizi interni.
Inoltre, è essenziale progettare i microservizi e le applicazioni client per gestire gli errori parziali, ovvero per creare microservizi e applicazioni client resilienti.