GH GambleHub

Timeout и controlul circuitului

1) De ce aveți nevoie de ea

Sistemele nu cad dintr-o defecțiune „fatală”, ci din acumularea de întârzieri și retrasări „val”. Limitarea timpului de așteptare și eliberarea resurselor, iar controlul circuitului (întrerupător + vărsare + competiție adaptivă) împiedică răspândirea degradării de-a lungul lanțului de dependențe. Scopul este de a menține p95/p99 în limitele țintă și de a menține disponibilitatea pentru eșecuri parțiale.


2) Definiții de bază

2. 1 Tipuri de intervale de timp (L7/L4)

Conectați timeout - Stabiliți o conexiune TCP/TLS.
TLS/Strângere de mână timeout - strângeri de mână TLS/HTTP2 prefață.
Scrieți timeout - trimiteți o cerere (inclusiv un corp).
Citiți timeout - așteptați primul octet al răspunsului și/sau al întregului corp.
Idle/Keep-Alive timeout - conexiune inactivă.
Termenul general - termenul limită „greu” pentru întreaga cerere (end-to-end).

2. 2 Bugetul limită

Selectați ținta „deadline _ total” și împărțiți pe etape:
  • 'ingress (gateway) + authZ + app + DB/cache + PSP de ieșire'.
Exemplu pentru plățile „POST” (400 ms target):
  • gateway: 30 ms,
  • cerere: 120 ms,
  • DB: 120 ms,
  • PSP: 100 ms,
  • marjă: 30 ms.

2. 3 Propagarea și anularea

"deadline "/" timeout 'trebuie transmis în jos lanțul (context, anteturi, gRPC Deadline). La expirare - anulați operațiunile de fundal (anulare/anulare ctx), ștergeți încuietorile/semafoarele.


3) Stabilirea strategiilor de timeout

1. Sus în jos: pe baza SLO și p95 - setați termenul limită end-to-end, apoi împărțiți în sub-timeout.
2. Identificați căile „scumpe” (descărcări de fișiere, rapoarte, PSP-uri externe) - individuale mai lungi, dar limitate.

3. Idempotent vs scrie:
  • idempotent (repetiții GET/stare) - mai scurt, mai agresiv;
  • scrie/monetar - puțin mai lung, dar cu o singură repetare și idempotență.
  • 4. Absolvirea prin planuri/chiriași (întreprinderea poate avea o perioadă mai lungă de timp, dar mai puțin paralelism).


4) Întrerupător de circuit: modele și parametri

4. 1 Politici de declanșare

Rata de eșec - rata de eroare ≥ X% pe fereastra de interogare/timp N.
Eșecuri consecutive: M eșecuri consecutive.
Rata apelurilor lente - proporția apelurilor mai lungi decât pragul T.
Clase de erori: timeouts/5xx/connection-reset → „fatal”, 4xx - nu luați în considerare.

4. 2 Condiții

Închis - sare peste tot, acumulează statistici.
Deschideți - eșec instantaneu (economisește resurse, nu zdrobește dependența).
Jumătate deschis - mici „eșantioane” (cereri N) pentru „testarea apei”.

4. 3 Adăugări utile

Perete etanș: un bazin de fire/conexiuni pe dependență, astfel încât să nu „suge” totul.
Concurență adaptivă: restricție automată de concurență (algoritmi AIMD/Vegas) prin latență observată.
Descărcarea încărcăturii: eșec precoce/degradare în caz de lipsă de resurse locale (cozi, CPU, GC pauze).


5) Interacțiune: timeout, retrageri, limite

Primul termen limită, apoi retransmiterea: fiecare repetare ar trebui să se încadreze într-un termen comun.
Backoff + jitter pentru reluări; respectați „Retry-After” și încercați din nou bugetul.
Limitarea ratei: Cu întrerupător deschis - limite mai mici pentru a nu intensifica furtuna.
Idempotency: obligatoriu pe operații de scriere (pentru a evita ia cu „prost” timeout).
În cazul în care pentru a retrage: de preferință la marginea (client/gateway), mai degrabă decât adânc în interior.


6) Valori țintă practice (repere)

Public read API: end-to-end "200-500 ms', citiți ora" 100-300 ms ".
Scriere critică (plăți): „300-800 ms” e2e; PSP extern ≤ "250-400 ms'.
Connect/TLS: '50-150 ms' (mai multe - probleme de rețea/lipit).
Inactiv: '30-90' (clienți mobili - mai scurt pentru a economisi baterie).
Ajustați valorile pentru p95/p99 și regiuni.


7) Configurări și exemple

7. 1 Trimis (cluster + traseu, pseudo)

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 (perimetru)

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 (Du-te)

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) Observabilitate și alertare

8. 1 Măsurători

'http _ client _ requires {endpoint, status}', 'client _ latency _ bucket'

'timeouts _ total {stage = connectcitestescriedeadline} '
'circuit _ state {dependency}': 0/1/2 (closed/half/open)
'slow _ call _ rate', 'failure _ ratee'
'active _ concurrency {route, dependency}'
'shed _ requires _ total {reason}' (load shedding)
'retry _ total {reason}', 'retry _ budget _ used'

8. 2 Trasee

Spans: handler → de intrare → DB/Redis → extern.
Atribute: 'timeout _ ms _ target', 'circuit _ state', 'queue _ time _ ms'.
Exemplare: Tie p99 vârfuri la anumite urme-id.

8. 3 Alerte

'p99 _ latency {critical}'> vizează X minute la rând.
'timeout _ rate {dependency}' hopped> Y%.
Tranziții frecvente la întrerupătorul „deschis ”/„ flapping”.
Growth of 'shed _ requires _ total' with high CPU/GC.


9) Adaptarea concurenței și a pierderii de sarcină

9. 1 Idee

Automatizarea reduce paralelismul pe măsură ce cozile de latență cresc:
  • AIMD: creșteți încet, scădeți brusc.
  • Vegas-cum ar fi: păstrați timpul de coadă.
  • Token-based: fiecare cerere „arde” jetonul; jetoanele sunt emise pe baza vitezei măsurate.

9. 2 Punerea în aplicare

Semafoare locale pe traseu; scopul este de a menține „coadă _ timp” sub prag.
„Siguranța” globală (RPS marginal/competitiv) pe poarta de acces.
Dacă există o lipsă de CPU/conexiuni, eșec timpuriu înainte de execuția logică (429/503 cu 'Retry-After').


10) Scenarii de testare și haos

Injecție de latență: adăugați artificial 50-300 ms pe dependență.
Pierderea pachetului/după/picătură (tc/tbf, Toxiproxy).
Rotirea butonului: reducerea piscinelor de conectare, creșterea sarcinii la saturație.
Kill/Degradați o zonă/ciob (indisponibilitate parțială).
Verificări: nu „eșuează” furtuna din spate; întrerupătorul se deschide previzibil; dacă coada este în creștere.


11) Antipattern

Un „timeout de citire” global fără conectare detaliată/TLS/per-stage.
Lipsa unui termen limită comun → retroactive depășește SLO.
Retrai fără jitter și fără retry-buget.
Conexiuni „eterne” fără temporizări inactive → descriptori de scurgeri.
Breaker numara 4xx ca greseli fatale.
Nu anulați/abandonați activitatea → fundal continuă după timeout-ul clientului.
Timeout-urile sunt prea lungi pentru rețelele mobile/instabile.


12) Specificul iGaming/Finanțe

Scriere critică (depozite/ieșiri): o scurtă repetare cu Idempotency-Key, apoi „202 Acceptat” + sondare în loc de așteptări infinite.
PSP/banking: politici separate pe furnizori/regiuni (unele mai lente).
Plăți și limite responsabile: pentru blocări/recenzii - rapid '423/409', nu întindeți tranzacțiile „agățate”.
Raportare/agregare - rulați asincron (lot + resursă de stare).


13) Lista de verificare Prod Readiness

  • End-to-end termen de traseu critic (GET/POST) definit.
  • Bugetat pe etape; este activată propagarea termenului limită.
  • Connect/TLS/read/write/inactive configs on gateway and clients.
  • Întrerupător cu rata de eșec și praguri de apel lent; logica corectă pe jumătate deschisă.
  • Pereți etanși pe dependențe; limitele de concurență pe traseu.
  • Încărcați vărsarea înainte ca logica de afaceri să fie executată în timpul supraîncărcării.
  • Integrarea cu retrageri: backoff + jitter, reîncercați-buget, respectați 'Retry-After'.
  • Idempotency scrie, „Idempotency-Key” și outbox pentru evenimente.
  • Metrics: timeout/lent-call/breaker/coadă de timp/competitiv.
  • Teste de haos: injectarea de întârzieri/pierderi/eșecuri, degradarea zonelor.
  • Documentația clientului: calendare de eșantionare, coduri de răspuns, sfaturi de reluare.

14) TL; DR

Dați fiecărei cereri un termen limită greu, aranjați-l în etape și răspândiți-l în jos pe lanț. Gestionați defecțiunile prin întrerupător de circuit + pereți etanși + concurență adaptivă + vărsare de sarcină. Reluări - numai în termenul limită, cu jitter și buget; scrie - numai idempotent. Măsurați timeout/lent-call, statul întrerupătorului și „coadă _ timp”, conduceți în mod regulat teste de haos.

Contact

Contactați-ne

Scrieți-ne pentru orice întrebare sau solicitare de suport.Suntem mereu gata să ajutăm!

Pornește integrarea

Email-ul este obligatoriu. Telegram sau WhatsApp sunt opționale.

Numele dumneavoastră opțional
Email opțional
Subiect opțional
Mesaj opțional
Telegram opțional
@
Dacă indicați Telegram — vă vom răspunde și acolo, pe lângă Email.
WhatsApp opțional
Format: cod de țară și număr (de exemplu, +40XXXXXXXXX).

Apăsând butonul, sunteți de acord cu prelucrarea datelor dumneavoastră.