GH GambleHub

Timeout и circuit control

1) Por qué es necesario

Los sistemas no caen de una sola falla «fatal», sino de la acumulación de retrasos y retratos de «onda». Los temporizadores limitan el tiempo de espera y liberan recursos, y el control de circuitos (breaker + shedding + competencia adaptativa) no permite que la degradación se extienda por la cadena de dependencias. El objetivo es mantener p95/p99 dentro de los límites de destino y mantener la disponibilidad en caso de fallos parciales.


2) Definiciones básicas

2. 1 Tipos de temporizadores (L7/L4)

Connect timeout - Establecer una conexión TCP/TLS.
TLS/Handshake timeout - apretones de mano TLS/HTTP2 preface.
Tiempo escrito: enviar una solicitud (incluido el cuerpo).
Tiempo de lectura: espera el primer byte de respuesta y/o cuerpo completo.
Idle/Keep-Alive timeout es una conexión inactiva.
Overall deadline es un término «duro» para toda la solicitud (fin a fin).

2. 2 Presupuesto de tiempo de espera (budget deadline)

Resaltamos el objetivo 'deadline _ total' y lo dividimos por etapas:
  • `ingress (gateway) + authZ + app + DB/cache + outbound PSP`.
Ejemplo para payments 'POST' (objetivo 400 ms):
  • Puerta de enlace: 30 ms,
  • aplicación: 120 ms,
  • DB: 120 ms,
  • PSP: 100 ms,
  • stock: 30 ms.

2. 3 Propagación y cancelación

'deadline '/' timeout' debe transmitirse por la cadena (contexto, encabezados, gRPC Deadline). Cuando caduca, cancela las operaciones de fondo (abort/ctx cancel), borra los bloqueos/semáforos.


3) Estrategias de instalación de temporizadores

1. Arriba-Abajo: Basado en SLO y p95 - Establecer el fin a fin deadline, a continuación, dividir en bajo-tiempo.
2. Identificar rutas «caras» (descarga de archivos, informes, PSPs externos) - individuales más largas pero limitadas.

3. Idempotent vs write:
  • idempotent (GET/repeticiones de estado) - más corto, más agresivo;
  • escritura/dinero - un poco más largo, pero con una sola repetición e idempotencia.
  • 4. Graduar por planos/tenantes (enterprise puede tener un tiempo más largo, pero menor paralelismo).


4) Circuit breaker: modelos y parámetros

4. 1 Políticas de activación

Failure-rate: porcentaje de errores ≥ X% en la ventana N de consultas/tiempo.
Fallas consecutivas: M contratiempos consecutivos.
Tasa de llamada lenta: la proporción de llamadas es más larga que el umbral T.
Error classes: timeouts/5xx/connection-reset → «fatal», 4xx - no tenemos en cuenta.

4. 2 Estados

Cerrado - salta todo, acumula estadísticas.
Open es una falla instantánea (ahorra recursos, no presiona la dependencia).
Half-open son pequeños «muestreos» (N solicitudes) para «chequear el agua».

4. 3 Complementos útiles

Bulkhead (spangouts): grupo de hilos/conexiones por dependencia para que uno no «chupe» todo.
Concurrencia adaptativa: restricción automática de concurrencia (algoritmos similares a AIMD/Vegas) por latencia observada.
Carga Shedding: Falla/degradación temprana cuando falta un recurso local (colas, CPU, pausas de GC).


5) Interacción: temporizadores, retraídos, límites

Primero deadline, luego retrae: cada repetición debe acomodarse en un deadline común.
Backoff + jitter para repeticiones; respetar 'Retry-After' y retry-budget.
Rate limiting: con breaker abierto: reduce los límites para no aumentar la tormenta.
Idempotencia: obligatoria en operaciones de escritura (para evitar tomas en timautas «mudos»).
Dónde retraer: preferiblemente en el borde (cliente/gateway) en lugar de en el interior.


6) Valores objetivo prácticos (puntos de referencia)

API de lectura pública: end-to-end '200-500 ms', read timeout '100-300 ms'.
Escritura crítica (pagos): '300-800 ms' e2e; PSP externo ≤ '250-400 ms'.
Connect/TLS: '50-150 ms' (más - problema de la red/resolview).
Idle: '30-90 s' (los clientes móviles son más cortos para ahorrar batería).
Ajuste los valores por p95/p99 y regiones.


7) Configuraciones y ejemplos

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 (perímetro)

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 (cliente, Go-pseudo)

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

7. 4 cliente 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) Observabilidad y alertinges

8. 1 Métricas

`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 Tracks

Durmientes: ingress → handler → DB/Redis → externos.
Atributos: 'timeout _ ms _ target', 'circuit _ state', 'queue _ time _ ms'.
Exemplares: atar picos p99 a un trace-id específico.

8. 3 Alertas

'p99 _ latency {critical}'> objetivos X minutos seguidos.
'timeout _ rate {dependency}' salto> Y%.
Transiciones frecuentes en el breaker 'open '/' flapping'.
Crecimiento de 'shed _ requests _ total' en CPU/GC alto.


9) Adaptive Concurrency & Load Shedding

9. 1 Idea

La automatización reduce el paralelismo en el crecimiento de las colas de latencia:
  • AIMD: aumentar lentamente, reducir drásticamente.
  • Vegas-similar: mantener la cola de destino (queue time).
  • Token-based: cada solicitud «quema» un token; los tokens se emiten a la velocidad medida.

9. 2 Implementación

Semáforos locales per-route; objetivo: mantener 'queue _ time' por debajo del umbral.
Un «fusible» global (límite RPS/competencia) en la puerta de enlace.
En caso de escasez de CPU/conexiones, se produce una falla temprana antes de ejecutar la lógica (429/503 con 'Retry-After').


10) Pruebas y escenarios de caos

Latency injection: añadir artificialmente 50-300 ms por dependencia.
Packet loss/dup/drop (tc/tbf, Toxiproxy).
Knob turning: reducir los grupos de conexiones, elevar la carga a saturation.
Kill/Degrade una zona/shard (inaccesibilidad parcial).
Comprobaciones: no «falla» si la tormenta retray; breaker se abre previsiblemente; si la cola no está creciendo.


11) Antipattern

Un «read timeout» global sin detalle connect/TLS/PE.
La falta de una línea de salida → retrabajo común va más allá del SLO.
Retrés sin jitter y sin retry-budget.
Conexiones «eternas» sin idle-timeout → filtraciones de descriptores.
Breaker considera los 4xx como errores fatales.
No hay cancelación/abort → el trabajo de fondo continúa después del tiempo de espera del cliente.
Tiempos de espera demasiado largos para redes móviles/inestables.


12) Especificidad de iGaming/finanzas

Escritura crítica (depósitos/retiros): una repetición corta con Idempotency-Key, luego '202 Acepted' + polling en lugar de expectativas infinitas.
PSP/banca: políticas separadas por proveedor/región (algunas más lentas).
Pagos responsables y límites: cuando bloqueos/rugidos - rápido '423/409', no estirar las operaciones «colgantes».
Informes/agregaciones: ejecutar asincrónicamente (batch + status resource).


13) Lista de comprobación prod

  • Definido por fin a fin por ruta crítica (GET/POST).
  • Presupuesto distribuido por etapas; habilita la propagación de la línea de salida.
  • Configuraciones connect/TLS/read/write/idle de temporizadores en gateway y clientes.
  • Circuito breaker con los umbrales failure-rate y slow-call; lógica half-open correcta.
  • Bulkheads en las dependencias; límites de paralelismo per-route.
  • Carga de carga antes de ejecutar la lógica de negocio en caso de sobrecarga.
  • Integración con retrés: backoff + jitter, retry-budget, respeto a 'Retry-After'.
  • Idempotencia write, 'Idempotency-Key' y outbox para los eventos.
  • Métricas: timeout/slow-call/estado breaker/queue time/competitividad.
  • Pruebas de caos: inyección de retrasos/pérdidas/fallas, degradación de zonas.
  • Documentación para clientes: ejemplos de temporizaciones, códigos de respuesta, consejos de repetición.

14) TL; DR

Dale a cada solicitud un deadline duro, esparcirlo por las etapas y esparcirlo por la cadena. Gestione las fallas a través de circuit breaker + bulkheads + adaptive concurrency + load shedding. Repeticiones - sólo dentro de la línea de salida, con el jitter y el presupuesto; write - sólo idempotente. Medir timeout/slow-call, estado breaker y 'queue _ time', correr pruebas de caos regularmente.

Contact

Póngase en contacto

Escríbanos ante cualquier duda o necesidad de soporte.¡Siempre estamos listos para ayudarle!

Iniciar integración

El Email es obligatorio. Telegram o WhatsApp — opcionales.

Su nombre opcional
Email opcional
Asunto opcional
Mensaje opcional
Telegram opcional
@
Si indica Telegram, también le responderemos allí además del Email.
WhatsApp opcional
Formato: +código de país y número (por ejemplo, +34XXXXXXXXX).

Al hacer clic en el botón, usted acepta el tratamiento de sus datos.