Resilience Patterns: timeout, retry, circuit breaker e bulkhead
Timeout, Retry, Circuit Breaker e Bulkhead limitano gli effetti a cascata delle dipendenze lente o indisponibili nelle piattaforme distribuite.
Perché la resilienza è parte dell'architettura
Quando un monolite diventa distribuito, ogni chiamata di rete introduce fallimenti parziali. Un sistema esterno può essere lento senza essere completamente down; un integration engine può saturarsi; un viewer può non rispondere. Senza limiti, una dipendenza lenta consuma thread e connessioni fino a rendere indisponibili servizi altrimenti sani.
Timeout
Ogni chiamata remota deve avere un timeout coerente con il caso d'uso. Timeout enormi non aumentano affidabilità: trattengono risorse e peggiorano il collasso a cascata. Connect timeout e read/response timeout vanno distinti e osservati.
Retry
Il retry è utile per errori transitori, ma deve avere limite, backoff e jitter. Non si ritenta automaticamente un errore funzionale 4xx o un comando non idempotente. Il retry indiscriminato durante un outage può moltiplicare il carico sulla dipendenza già in crisi.
Circuit Breaker
Il Circuit Breaker osserva i fallimenti e apre il circuito quando la dipendenza supera una soglia, facendo fail-fast. Dopo un intervallo passa in half-open e prova un numero limitato di richieste. Protegge risorse e riduce latenza durante indisponibilità persistenti.
Bulkhead
Il Bulkhead isola pool di thread, connessioni o code per impedire che il problema di una dipendenza esaurisca tutte le risorse del servizio. Le integrazioni lente verso un sistema esterno non dovrebbero bloccare anche le API interne sane.
Composizione corretta
Definire timeout realistico.
Applicare retry solo a errori transient e operazioni idempotenti.
Proteggere la dipendenza con Circuit Breaker.
Isolare le risorse con Bulkhead.
Esportare metriche: latency, timeout, retry, circuit state e queue saturation.
Fallback
Un fallback non deve inventare dati clinici o restituire silenziosamente informazioni obsolete come se fossero correnti. Può mostrare uno stato degradato, usare una cache esplicitamente marcata o disabilitare una funzione non critica. La degradazione deve essere visibile all'utente e all'osservabilità.
Regola finale
Retry senza timeout e idempotenza è spesso un amplificatore di guasti; timeout senza osservabilità è solo un errore più veloce.
