GH GambleHub

Timeout и circuit control

1) Perché è necessario

I sistemi non cadono da un singolo guasto «fatale», ma da un accumulo di ritardi e retra'onde '. I timeout limitano i tempi di attesa e rilasciano risorse, mentre il circuito control (breaker + shedding + competizione adattiva) impedisce che il degrado si diffonda attraverso la catena di dipendenze. L'obiettivo è di mantenere p95/p99 nei limiti di destinazione e mantenere la disponibilità in caso di guasti parziali.


2) Definizioni di base

2. 1 Viste timeout (L7/L4)

Connect timeout - Imposta una connessione TCP/TLS.
TLS/Handshake timeout - TLS/HTTP2 preface.
Write timeout - Invia una query (compreso il corpo).
Read timeout - aspettando la prima risposta byte e/o tutto il corpo.
Idle/Keep-Alive timeout è una connessione inattiva.
Overall deadline - Termine «rigido» per l'intera richiesta (end-to-end).

2. 2 Budget timeout (deadline budget)

Seleziona il target deadline _ total e suddivide per stadio:
  • `ingress (gateway) + authZ + app + DB/cache + outbound PSP`.
Esempio per payments «POST» (obiettivo 400 ms):
  • gateway: 30 ms,
  • applicazione: 120 ms,
  • Database: 120 ms,
  • PSP: 100 ms,
  • Riserva: 30 mc.

2. 3 Propagation e annullamento

«deadline »/« timeout» deve essere trasmesso in fondo alla catena (contesto, titoli, gRPC Deadline). Quando scade, annulla le operazioni di sfondo (abort/ctx cancel), cancella i blocchi/semafori.


3) Strategie di installazione timeout

1. Sopra e giù: in base a SLO e p95, impostare end-to-end deadline, quindi dividere in sotto-timeout.
2. Identificare percorsi «costosi» (caricamento di file, report, PSP esterni) sono singoli percorsi più lunghi ma limitati.

3. Idempotent vs write:
  • idempotent (GET/ripetizioni di stato) - più breve, più aggressivo;
  • write/denaro - leggermente più lungo, ma con ripetizione singola e idipotenza.
  • 4. Scala in base ai piani/tenanti (enterprise può avere un timeout più lungo, ma un parallelismo minore).


4) Circuito breaker: modelli e parametri

4. 1 Criteri di attivazione

Failure-rate: percentuale di errori X% nella finestra N query/ora.
Consultive failures: M fallimenti consecutivi.
Slow-call rate - Percentuale di chiamate superiore alla soglia T.
Errore classes: timeout/5xx/connection-reset «fatali», 4xx - non contate.

4. 2 Stati

Closed - salta tutto, accumula statistiche.
Open è un guasto istantaneo (risparmia risorse senza condizionare la dipendenza).
Half-open è un piccolo «campione» (N query) per «controllo dell'acqua».

4. 3 Integratori utili

Bullkhead - Un pool di flussi/connessioni di dipendenza in modo che uno non risucchi tutto.
Adattative concertency: limitazione automatica del parallelismo (AIMD/Vegas-algoritmi simili) sulla latitanza osservata.
Load Shedding: guasto precoce/degrado in caso di carenza di risorse locali (code, CPU, interruzioni GC).


5) Interazione: timeout, retrai, limiti

Prima la deadline, poi i retrai, ogni ripetizione deve entrare nella deadline comune.
Backoff + jitter per ripetizioni; Rispettare Retry-After e retry-budget.
Rate limiting: con breaker aperto - Abbassare i limiti per non aumentare la tempesta.
Idempotency è obbligatorio nelle operazioni write (per evitare le riprese durante i timeout muti).
Dove ritrarre: preferibilmente sul bordo (client/gateway) piuttosto che nel profondo.


6) Target pratici (punti di riferimento)

Read API pubblica: end-to-end '200-500 ms', read timeout '100-300 ms'.
write (pagamenti) critici: '300-800 ms' e2e; PSP esterno «250-400 ms».
Connect/TLS: '50-150 ms' (più grande è un problema di rete/soluzione).
Idle: «30-90» (client mobili - più breve per risparmiare la batteria).
Regolate i valori per p95/p99 e regioni.


7) Confighi e esempi

7. 1 Invoy (cluster + route, pseudonimo)

yaml clusters:
- name: payments_psp connect_timeout: 100ms type: STRICT_DNS lb_policy: ROUND_ROBIN circuit_breakers:
thresholds:
- priority: DEFAULT max_connections: 2000 max_requests: 2000 max_retries: 50 outlier_detection:
consecutive_5xx: 5 interval: 5s base_ejection_time: 30s max_ejection_percent: 50

routes:
- match: { prefix: "/api/v1/payments" }
route:
cluster: payments_psp timeout: 350ms        # per-request deadline idle_timeout: 30s retry_policy:
retry_on: "reset,connect-failure,refused-stream,5xx,gateways"
num_retries: 1 per_try_timeout: 200ms

7. 2 NGINX (perimetro)

nginx proxy_connect_timeout 100ms;
proxy_send_timeout  200ms;  # write proxy_read_timeout  300ms;  # read (первый байт/все тело)
keepalive_timeout   30s;
send_timeout     15s;

Быстрый отказ при перегрузке limit_conn_zone $binary_remote_addr zone=addr:10m;
limit_conn addr 50;

7. 3 gRPC (client, Go-pseudo)

go ctx, cancel:= context.WithTimeout(context.Background(), 350time.Millisecond)
defer cancel()
resp, err:= client.Pay(ctx, req) // Deadline передается вниз

7. 4 client HTTP (Go)

go client:= &http.Client{
Timeout: 350 time.Millisecond, // общий дедлайн на запрос
Transport: &http.Transport{
TLSHandshakeTimeout: 100 time.Millisecond,
ResponseHeaderTimeout: 250 time.Millisecond,
IdleConnTimeout: 30 time.Second,
MaxIdleConnsPerHost: 100,
},
}

7. 5 Resilience4j (Java, pseudo)

yaml resilience4j.circuitbreaker.instances.psp:
slidingWindowType: TIME_BASED slidingWindowSize: 60 failureRateThreshold: 50 slowCallDurationThreshold: 200ms slowCallRateThreshold: 30 permittedNumberOfCallsInHalfOpenState: 5 waitDurationInOpenState: 30s

resilience4j.timelimiter.instances.psp:
timeoutDuration: 350ms

8) Osservabilità e alerting

8. 1 Metriche

`http_client_requests{endpoint, status}`, `client_latency_bucket`

`timeouts_total{stage=connectreadwritedeadline}`
`circuit_state{dependency}`: 0/1/2 (closed/half/open)
`slow_call_rate`, `failure_rate`
`active_concurrency{route, dependency}`
`shed_requests_total{reason}` (load shedding)
`retry_total{reason}`, `retry_budget_used`

8. 2 Roulotte

Spans: ingress → handler → DB/Redis → esterni.
Attributi: 'timeout _ ms _ target', 'circuito _ state', 'queue _ time _ ms'.
Esemplar: aggancia picchi p99 a particolari trace-id.

8. 3 Alerti

'p99 _ latency {critical}'> obiettivi X minuti consecutivi.
«timeout _ rate {dipendency}» è saltato> Y%.
Frequenti passaggi a «open »/« flapping» breaker.
Altezza di «shed _ sollests _ total» con CPU/GC elevato.


9) Adaptive Concurrency & Load Shedding

9. 1 Idea

L'automazione riduce il parallelismo quando crescono le code di latitanza:
  • AMD: aumentare lentamente, abbassare drasticamente.
  • Vegas-simile - Mantenere la coda di destinazione (queue time).
  • Token-based: ogni query «brucia» il token; i token vengono rilasciati a velocità misurata.

9. 2 Implementazione

Semafori locali per-route; l'obiettivo è tenere «queue _ time» sotto la soglia.
Fusibile globale (RPS/Competition Limite) sul gateway.
In caso di carenza di CPU/connessioni, si verifica un errore iniziale prima della logica (429/503 con'Retry-After ').


10) Test e script di caos

Latency injection - aggiungere artificialmente 50-300 ms per dipendenza.
Packet loss/dup/drop (tc/tbf, Toxiproxy).
Knob turning: riduce i pool di connessione, aumenta il carico a saturation.
Kill/Degrade una zona/shard (non disponibile parzialmente).
Controlli: Non «fallisce» se la tempesta di retro; breaker si apre prevedibilmente; Non c'è una coda in aumento.


11) Antipattern

Un read timeout globale senza i dettagli connect/TLS/per-stadio.
L'assenza di deadline generico va oltre lo SLO.
Retrai senza jitter e senza retry-budget.
Connessioni «eterne» senza idle-timeout per la fuga di descrittori.
Breaker considera il 4xx come un errore fatale.
Nessuna cancellazione/abort. I lavori di sfondo continuano dopo il timeout del cliente.
Timeout troppo lunghi per reti mobili/instabili.


12) Specificità iGaming/finanza

Write critici (depositi/conclusioni): una breve ripetizione con Idempotency-Key, poi «202 Accetted» + polling invece di infinite aspettative.
PSP/banking: regole separate per il provider/regione (alcune più lente).
Pagamenti responsabili e limiti: in caso di blocchi/gelosie è veloce «423/409», non allungare le transazioni «pendenti».
Report/aggregazione - Avvia asincrona (batch + stato-risorsa).


13) Assegno-foglio prod-pronto

  • Definito end-to-end deadline attraverso percorsi critici (GET/POST).
  • Bilancio per stadio decomposto; La propagazione della deadline è attivata.
  • Confighi connect/TLS/read/write/idle timeout su gateway e client.
  • Circuito breaker con soglie failure-rate e slow-call; corretta logica half-open.
  • Bullkheads per dipendenza; limiti di parallelismo per-route.
  • Load shedding prima di eseguire la logica aziendale durante il sovraccarico.
  • Integrazione con i retrai: backoff + jitter, retry-budget, rispetto «Retry-After».
  • Idempotence write, Idempotency-Key e outbox per gli eventi.
  • Metriche: timeout/slow-call/stato breaker/queue time/competitività.
  • Test di caos: iniezione di ritardi/perdite/guasti, degrado delle zone.
  • Documentazione per i clienti: esempi di timing, codici di risposta, suggerimenti di ripetizione.

14) TL; DR

Date a ciascuna richiesta una deadline rigida, posizionatela per stadio e diffondetela in fondo alla catena. Gestisci i guasti attraverso il circuito breaker + bulkheads + adattativo concertency + load shedding. Ripetizioni solo all'interno della deadline, con jitter e budget; write - solo idipotenti. Misurare timeout/slow-call, stato breaker e «queue _ time», eseguire regolarmente test di caos.

Contact

Mettiti in contatto

Scrivici per qualsiasi domanda o richiesta di supporto.Siamo sempre pronti ad aiutarti!

Avvia integrazione

L’Email è obbligatoria. Telegram o WhatsApp — opzionali.

Il tuo nome opzionale
Email opzionale
Oggetto opzionale
Messaggio opzionale
Telegram opzionale
@
Se indichi Telegram — ti risponderemo anche lì, oltre che via Email.
WhatsApp opzionale
Formato: +prefisso internazionale e numero (ad es. +39XXXXXXXXX).

Cliccando sul pulsante, acconsenti al trattamento dei dati.