Módulo 07Trimestre 3 · Fiabilidad y escala8 puntos del póster

Patrones de resiliencia

Inicia sesión para guardar tu progreso en todos tus dispositivos. Mientras tanto, se guarda en este navegador.

Por qué importa

Toda llamada externa (base de datos, pasarela de pagos, proveedor de LLM, SMS) en algún momento será lenta, fallará o fallará a medias. El código generado por IA casi siempre asume el camino feliz. Una sola dependencia lenta sin timeout puede tumbar toda tu app al agotar hilos, conexiones o la concurrencia serverless.

Resultados de aprendizaje

  1. Poner un timeout a cada llamada saliente y definirlo a partir de un presupuesto de latencia.
  2. Reintentar de forma segura: solo operaciones idempotentes, con backoff exponencial y jitter, y con un límite.
  3. Usar circuit breakers y fallbacks para degradar con elegancia.
  4. Aplicar backpressure y dead letter queues para que la sobrecarga y los mensajes envenenados no provoquen fallos en cascada.
  5. Exponer health checks con significado real.

Lecciones

7.1 Timeouts (11)

  • En muchos clientes HTTP, el timeout por defecto es infinito o de varios minutos. Defínelo de forma explícita: timeout de conexión + timeout de petición.
  • Dedúcelo de un presupuesto: si la página debe responder en 2 s y llama a tres servicios en secuencia, cada uno recibe bastante menos de 2 s.
  • Propaga los deadlines: si al llamante le quedan 300 ms, no inicies una llamada de 2 s.
  • Llamadas a LLM: usa streaming con timeout para el primer token y timeout total.

7.2 Reintentos y backoff exponencial (12, 13)

  • Reintenta solo errores transitorios (timeouts, 429, 502, 503, 504, conexiones reiniciadas). Nunca reintentes 400/401/403/422.
  • Reintenta solo operaciones idempotentes, o que lleven una idempotency key (04 · APIs y contratos).
  • Backoff: delay = min(cap, base * 2^attempt) más jitter aleatorio para que miles de clientes no reintenten sincronizados (thundering herd).
  • Limita los intentos (a menudo 3) y el tiempo total. Respeta Retry-After.
  • Reintenta en una sola capa. Los reintentos en cada capa se multiplican: 3 x 3 x 3 = 27 llamadas por cada acción del usuario.

7.3 Circuit breakers (10)

Estados: cerrado (normal) → abierto al superar el umbral de fallos (falla rápido, sin llamadas) → semiabierto tras el periodo de enfriamiento (deja pasar unas pocas para probar) → cerrado si está sano. Combínalo con un fallback: datos en caché, una funcionalidad degradada, un "te avisaremos" en cola o un proveedor secundario (por ejemplo, un segundo proveedor de LLM).

7.4 Bulkheads y backpressure (44)

  • Bulkheads (compartimentos estancos): pools y límites separados por dependencia, para que un LLM lento no consuma la capacidad que necesita tu endpoint de login.
  • Backpressure: cuando los consumidores no dan abasto, devuelve la presión (colas acotadas, 429/503 con Retry-After, descarte del trabajo de baja prioridad) en lugar de acumular en buffer hasta quedarte sin memoria.

7.5 Dead letter queues (20)

Tras N intentos de procesamiento fallidos, mueve el mensaje a una DLQ en lugar de reintentarlo para siempre (un "mensaje envenenado" puede bloquear una cola). Configura alertas sobre la profundidad de la DLQ. Construye una herramienta para inspeccionar, corregir y reprocesar.

7.6 Health checks (56, 57)

  • Liveness: "¿está vivo el proceso?". Barato; nunca comprueba dependencias (si no, un microcorte de la base de datos reinicia todos los pods).
  • Readiness: "¿puedo servir tráfico ahora?". Comprueba las dependencias críticas; si da falso, saca la instancia del balanceador de carga.
  • Startup: para servicios que tardan en arrancar.
  • Una página de estado pública alimentada por checks sintéticos del recorrido real del usuario.

7.7 Degradación elegante

Decide por funcionalidad: ¿qué ve el usuario cuando esta dependencia está caída? Déjalo por escrito. Ejemplos: las recomendaciones se ocultan, los pagos se ponen en cola con un mensaje claro, el asistente de IA muestra "no disponible temporalmente" en vez de un spinner eterno.

Lab 7: Caos en tu portátil

Usa Toxiproxy (o un middleware de inyección de fallos) entre tu app y sus dependencias.

  1. Añade 5 s de latencia al proveedor de LLM. Observa. Añade timeouts, reintentos con jitter, circuit breaker y fallback. Vuelve a observar.
  2. Haz que el proveedor de pagos devuelva 503 en el 50% de las llamadas. Demuestra que no hay cobros duplicados.
  3. Inyecta un mensaje envenenado en tu cola; demuestra que acaba en la DLQ y genera una alerta.
  4. Tumba la base de datos durante 30 s. Readiness falla, liveness sigue en pie y el servicio se recupera sin reiniciarse.

Definition of Done

Paquete de prompts de IA

  • "Encuentra todas las llamadas de red salientes de este repo. Indica cuáles no tienen timeout, cuáles reintentan operaciones no idempotentes y cuáles no tienen fallback."
  • "Crea un cliente HTTP compartido con timeouts, reintentos solo ante errores transitorios con backoff exponencial y full jitter, y un circuit breaker por host."