Timeout и circuit control
1) Warum es notwendig ist
Die Systeme fallen nicht durch einen einzigen „fatalen“ Fehler, sondern durch die Anhäufung von Verzögerungen und „Wave“ -Retrays. Timeouts begrenzen Wartezeiten und setzen Ressourcen frei, und die Schaltungssteuerung (Breaker + Shedding + Adaptive Competition) verhindert, dass sich die Degradation entlang der Abhängigkeitskette ausbreitet. Ziel ist es, p95/p99 innerhalb der Zielgrenzen zu halten und die Verfügbarkeit bei Teilausfällen zu erhalten.
2) Grundlegende Definitionen
2. 1 Arten von Timeouts (L7/L4)
Connect timeout - Aufbau einer TCP/TLS-Verbindung.
TLS/Handshake Timeout - Handshake TLS/HTTP2 Preface.
Timeout schreiben - Senden Sie eine Anfrage (einschließlich des Körpers).
Timeout lesen - Warten auf das erste Byte der Antwort und/oder den ganzen Körper.
Idle/Keep-Alive Timeout ist eine inaktive Verbindung.
Total deadline - „harte“ Frist für die gesamte Anfrage (Ende-zu-Ende).
2. 2 Zeitlimitbudget (Deadline Budget)
Wir markieren das Ziel 'deadline _ total' und teilen es in Stufen:- `ingress (gateway) + authZ + app + DB/cache + outbound PSP`.
- Gateway: 30 ms,
- Anwendung: 120 ms,
- DB: 120 ms,
- PSP: 100 ms,
- Reserve: 30 ms.
2. 3 Propagation und Stornierung
'deadline '/' timeout' muss entlang der Kette (Kontext, Header, gRPC Deadline) weitergegeben werden. Bei Ablauf - Abbruch der Hintergrundoperationen (Abbruch/CTX-Abbruch), Bereinigung der Sperren/Semaphoren.
3) Timeout-Installationsstrategien
1. Von oben nach unten: Basierend auf SLO und p95 - End-to-End-Deadline festlegen und dann in Sub-Timeouts aufteilen.
2. Identifizieren Sie „teure“ Pfade (Dateidownload, Berichte, externe PSPs) - einzelne länger, aber begrenzt.
- idempotent (GET/Statuswiederholungen) - kürzer, aggressiver;
- Schreiben/Geld - etwas länger, aber mit einmaliger Wiederholung und Idempotenz.
4. Abstufung nach Plänen/Tenanten (Unternehmen kann einen längeren Timeout, aber weniger Parallelität haben).
4) Circuit Breaker: Modelle und Parameter
4. 1 Auslöserichtlinien
Failure-Rate: Fehlerquote ≥ X% im N-Request/Time-Fenster.
Consecutive failures: M in Folge des Scheiterns.
Slow-Call-Rate: Der Anteil der Anrufe ist länger als die T-Schwelle.
Error classes: timeouts/5xx/connection-reset → „fatal“, 4xx - nicht berücksichtigt.
4. 2 Zustände
Geschlossen - überspringt alles, sammelt Statistiken.
Öffnen - sofortiger Ausfall (spart Ressourcen, drückt die Abhängigkeit nicht).
Half-open - kleine „Proben“ (N-Anfragen) für den „Wassercheck“.
4. 3 Nützliche Ergänzungen
Bulkhead (Spangouts): Pool von Threads/Verbindungen pro Abhängigkeit, so dass man nicht alles „saugt“.
Adaptive Concurrency: Automatische Begrenzung der Parallelität (AIMD/Vegas-ähnliche Algorithmen) durch die beobachtete Latenz.
Load Shedding: frühzeitiger Ausfall/Degradation bei fehlender lokaler Ressource (Warteschlangen, CPU, GC-Pausen).
5) Interaktion: Timeouts, Retrays, Limits
Erst Deadline, dann Retrays: Jede Wiederholung muss in eine gemeinsame Deadline passen.
Backoff + jitter für Wiederholungen; respektieren 'Retry-After' und Retry-Budget.
Rate Limiting: Bei offenem Breaker - Grenzen senken, um den Sturm nicht zu verstärken.
Idempotency: obligatorisch bei Write-Operationen (um Takes bei „stummen“ Timeouts zu vermeiden).
Wo zurückziehen: vorzugsweise am Rand (Client/Gateway) und nicht tief im Inneren.
6) Praktische Zielwerte (Benchmarks)
Öffentliche Lese-API: Ende-zu-Ende' 200-500 ms', Lese-Timeout '100-300 ms'.
Kritische Schreibvorgänge (Zahlungen): „300-800 ms“ e2e; Externe PSP ≤ '250-400 ms'.
Connect/TLS: '50-150 ms' (mehr ist ein Netzwerk-/Solvolving-Problem).
Idle: '30-90 s' (mobile Clients - kurz, um Batterie zu sparen).
Werte nach p95/p99 und Regionen korrigieren.
7) Configs und Beispiele
7. 1 Envoy (Cluster + Route, 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 (Perimeter)
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 HTTP-Client (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) Beobachtbarkeit und Warnungen
8. 1 Metriken
`http_client_requests{endpoint, status}`, `client_latency_bucket`
8. 2 Treysa
Spans: ingress → handler → DB/Redis → extern.
Attribute: 'timeout _ ms _ target', 'circuit _ state', 'queue _ time _ ms'.
Exemplare: Binden Sie p99-Peaks an bestimmte Trace-id.
8. 3 Alerts
'p99 _ latency {critical}'> Ziel X Minuten hintereinander.
'timeout _ rate {dependency}' sprunghaft> Y%.
Häufige Übergänge zum 'open '/' flapping' breaker.
Wachstum von 'shed _ requests _ total' bei hoher CPU/GC.
9) Adaptive Concurrency & Load Shedding
9. 1 Idee
Die Automatisierung reduziert die Parallelität beim Wachstum von Latenzschwänzen:- AIMD: langsam erhöhen, stark reduzieren.
- Vegas-like: Halten Sie die Zielwarteschlange (queue time).
- Token-basiert: Jede Abfrage "verbrennt' ein Token; Token werden mit der gemessenen Geschwindigkeit ausgegeben.
9. 2 Umsetzung
Lokale Semaphoren per Route; Ziel ist es, 'queue _ time' unter dem Schwellenwert zu halten.
Globale „Sicherung“ (ultimate RPS/competitiveness) am Gateway.
Wenn CPU/Verbindungen fehlen - früher Ausfall vor Ausführung der Logik (429/503 mit 'Retry-After').
10) Test- und Chaos-Szenarien
Latenzinjektion: künstlich 50-300 ms pro Abhängigkeit hinzufügen.
Packet loss/dup/drop (tc/tbf, Toxiproxy).
Knob turning: Reduzieren Sie die Verbindungspools, erhöhen Sie die Last bis zur Sättigung.
Kill/Degrade one zone/shard (teilweise nicht verfügbar).
Kontrollen: Es „scheitert“ nicht, ob der Retray-Sturm; Breaker öffnet vorhersehbar; ob die Schlange wächst.
11) Antipatterns
Ein globaler „Read Timeout“ ohne Connect/TLS/Per-Stage-Details.
Das Fehlen eines allgemeinen Termins → Retrays geht über den SLO hinaus.
Retrays ohne Jitter und ohne Retry-Budget.
„Ewige“ Verbindungen ohne Idle-Timeouts → Leaks von Deskriptoren.
Breaker betrachtet 4xx als fatale Fehler.
Keine Stornierung/Abbruch → Hintergrundarbeit wird nach der Client-Zeitüberschreitung fortgesetzt.
Die Timeouts für mobile/instabile Netzwerke sind zu lang.
12) Spezifität von iGaming/Finanzen
Critical Write (Ein-/Auszahlungen): eine kurze Wiederholung mit dem Idempotency-Key, dann '202 Accepted' + Polling statt endloser Erwartungen.
PSP/Banking: getrennte Richtlinien nach Anbieter/Region (einige langsamer).
Verantwortungsvolle Zahlungen und Limits: Mit Sperren/Revue - schnell '423/409', „hängende“ Operationen nicht strecken.
Reporting/Aggregation - asynchron ausführen (Batch + Status Ressource).
13) Checkliste Prod-Ready
- End-to-End-Deadline über kritische Routen (GET/POST) definiert.
- Das Budget ist nach Stufen gegliedert; propagation deadline ist aktiviert.
- Confighi connect/TLS/read/write/idle timeouts auf Gateway und Clients.
- Circuit Breaker mit Failure-Rate und Slow-Call-Schwellenwerten; korrekte halb-offene Logik.
- Bulkheads auf Abhängigkeiten; Grenzen der Parallelität pro Route.
- Lade Shedding, bevor die Geschäftslogik bei Überlast ausgeführt wird.
- Integration mit Retrays: Backoff + Jitter, Retry-Budget, Respekt vor 'Retry-After'.
- Schreibidempotenz, 'Idempotency-Key' und Outbox für Events.
- Metriken: timeout/slow-call/breaker state/queue time/competitiveness.
- Chaos-Tests: Injektion von Verzögerungen/Verlusten/Ausfällen, Degradation von Zonen.
- Dokumentation für Kunden: Beispiele für Timings, Antwortcodes, Tipps für Wiederholungen.
14) TL; DR
Geben Sie jeder Anfrage eine harte Frist, verteilen Sie sie in Stufen und verteilen Sie sie in der Kette. Verwalten Sie Fehler über Circuit Breaker + Bulkheads + adaptive Concurrency + Load Shedding. Wiederholungen - nur innerhalb der Frist, mit Jitter und Budget; write - nur idempotent. Messen Sie Timeout/Slow-Call, Breaker-Status und 'queue _ time', fahren Sie regelmäßig Chaos-Tests.