Errores, Reintentos y Resiliencia

Patrones Intermediate 20 min Jan 12, 2026

Audiencia

Esta guía es para desarrolladores que necesitan construir integraciones confiables con APIs:

  • Desarrolladores backend implementando clientes de API que necesitan manejar fallos correctamente
  • Desarrolladores frontend construyendo aplicaciones que permanezcan responsivas cuando las APIs fallan
  • Arquitectos de sistemas diseñando sistemas distribuidos resilientes
  • Ingenieros DevOps entendiendo patrones de fallo para mejorar monitoreo y alertas
  • Cualquiera que haya experimentado frustración con APIs que expiran, devuelven errores o se vuelven inaccesibles

Debes estar familiarizado con los conceptos básicos de HTTP. Si no, comienza con HTTP para APIs REST.

Objetivo

Después de leer esta guía, entenderás:

  • Por qué fallan las APIs y las diferentes categorías de fallos
  • Qué son los timeouts y por qué son críticos para la salud del sistema
  • Cómo funcionan las estrategias de reintento, incluyendo backoff exponencial y jitter
  • Por qué importa la idempotencia y cómo las claves de idempotencia previenen duplicados
  • Cómo el patrón circuit breaker protege tu sistema de fallos en cascada
  • Qué significa la degradación elegante y cuándo aplicarla

No estarás configurando patrones de resiliencia listos para producción todavía, pero tendrás un modelo mental sólido de cómo los sistemas resilientes manejan los fallos.

1. Por Qué Fallan las APIs

Las APIs fallan. No ocasionalmente—constantemente. Entender los modos de fallo es el primer paso para construir sistemas resilientes.

Categorías de Fallos

Los fallos de API caen en categorías distintas, cada una requiriendo un manejo diferente:

graph TD
    F[Fallo de API] --> N[Fallos de Red]
    F --> T[Fallos de Timeout]
    F --> O[Fallos de Sobrecarga]
    F --> B[Fallos por Bugs]
    F --> D[Fallos de Dependencias]

    N --> N1[Conexión rechazada]
    N --> N2[Resolución DNS fallida]
    N --> N3[Handshake TLS fallido]

    T --> T1[Timeout de lectura]
    T --> T2[Timeout de conexión]
    T --> T3[Timeout de inactividad]

    O --> O1[Rate limiting - 429]
    O --> O2[Servidor sobrecargado - 503]
    O --> O3[Cola llena]

    B --> B1[Error del servidor - 500]
    B --> B2[Respuesta inesperada]
    B --> B3[Corrupción de datos]

    D --> D1[Base de datos caída]
    D --> D2[API externa falló]
    D --> D3[Cola de mensajes inaccesible]

    style F fill:#ffccbc
    style N fill:#fff9c4
    style T fill:#fff9c4
    style O fill:#fff9c4
    style B fill:#fff9c4
    style D fill:#fff9c4

Fallos de Red

La red entre tu cliente y la API puede fallar de muchas formas:

  • Conexión rechazada: El servidor no está aceptando conexiones
  • Fallo de DNS: No puede resolver el hostname a una dirección IP
  • Errores TLS: Certificado expirado, hostname no coincide, incompatibilidad de protocolo
  • Conexión reiniciada: La conexión fue cerrada forzosamente
  • Pérdida de paquetes: Los datos nunca llegan o se corrompen en tránsito

Los fallos de red son usualmente transitorios—se resuelven solos cuando la red se recupera.

Fallos de Timeout

Los timeouts ocurren cuando algo toma demasiado tiempo:

  • Timeout de conexión: Establecer la conexión TCP toma demasiado tiempo
  • Timeout de lectura: Esperar los datos de respuesta toma demasiado tiempo
  • Timeout de inactividad: La conexión estuvo sin uso demasiado tiempo

Los timeouts son ambiguos: ¿La petición tuvo éxito? Enviaste la petición, pero no sabes si el servidor la recibió, la procesó, o envió una respuesta que se perdió.

Fallos de Sobrecarga

Los servidores pueden verse abrumados:

  • Rate limiting (429): Estás enviando peticiones demasiado rápido
  • Servidor sobrecargado (503): El servidor no puede manejar la carga actual
  • Cola llena: Las colas de peticiones están saturadas

Los fallos de sobrecarga señalan: “Estoy muy ocupado, intenta más tarde.”

Fallos por Bugs

A veces el servidor mismo está roto:

  • 500 Internal Server Error: Excepción no manejada, puntero nulo, etc.
  • Formato de respuesta inesperado: La API cambió sin aviso
  • Errores de lógica: El servidor procesó la petición incorrectamente

Los fallos por bugs frecuentemente requieren intervención humana para arreglarlos.

Fallos de Dependencias

Las APIs modernas dependen de otros servicios:

  • Base de datos no disponible: No puede almacenar o recuperar datos
  • API externa falló: El servicio de terceros está caído
  • Fallo de caché: Redis/Memcached no disponible

Los fallos de dependencias se propagan en cascada—un servicio fallando puede tumbar muchos otros.

La Realidad del Fallo

En un sistema distribuido con múltiples servicios, los fallos son inevitables. Si cada servicio tiene 99.9% de uptime, una petición que toca 10 servicios tiene solo 99%^10 = 99% de tasa de éxito—1% de las peticiones fallan incluso cuando todo es “confiable.”

Construir sistemas resilientes significa aceptar que los fallos ocurren y diseñar para ellos.

2. Timeouts: Tu Primera Línea de Defensa

Un timeout es un límite de cuánto tiempo esperarás a que algo se complete. Sin timeouts, una API lenta o sin respuesta puede colgar toda tu aplicación.

Por Qué Importan los Timeouts

Imagina una API de pagos que se vuelve lenta. Sin timeouts:

sequenceDiagram
    participant C as Tu App
    participant P as API de Pagos

    C->>P: Procesar pago
    Note over P: API lenta...
    Note over C: Thread bloqueado
esperando para siempre Note over P: Aún procesando... Note over C: Más peticiones llegan
Todos los threads bloqueados Note over P: Más tiempo pasa... Note over C: Pool de threads agotado
Aplicación colgada style C fill:#ffccbc

Una dependencia lenta puede consumir todos tus recursos, haciendo que toda tu aplicación no responda. Esto se llama agotamiento de recursos.

Tipos de Timeouts

Timeout de conexión: Cuánto tiempo esperar al establecer una conexión.

  • Muy corto: Falla antes de que la conexión se complete en redes lentas
  • Muy largo: Recursos atados esperando servidores inalcanzables
  • Valores típicos: 1-10 segundos

Timeout de lectura (timeout de respuesta): Cuánto tiempo esperar datos de respuesta después de conectar.

  • Muy corto: Falla en operaciones legítimamente lentas
  • Muy largo: Recursos atados esperando servidores trabados
  • Valores típicos: 5-60 segundos (depende de la operación)

Timeout total: Tiempo máximo para todo el ciclo petición-respuesta.

  • Asegura tiempo de espera acotado sin importar los reintentos
  • Valores típicos: 30-120 segundos

El Dilema del Timeout

Configurar timeouts involucra compromisos:

Timeout Muy CortoTimeout Muy Largo
Falla peticiones legítimasFallos lentos
Alta tasa de erroresAgotamiento de recursos
Mala experiencia de usuarioLentitud en cascada

La idea clave: Un fallo rápido frecuentemente es mejor que un éxito lento. Tus usuarios preferirían ver “intenta de nuevo” que esperar para siempre.

Timeout como Contrato

Piensa en los timeouts como un contrato con tus usuarios: “Prometo responder dentro de X segundos, aunque la respuesta sea ‘No lo sé.’”

# Petición con contexto de timeout
POST /payments HTTP/1.1
X-Request-Timeout: 30

# El servidor debería abortar si no puede responder a tiempo

Sin este contrato, el tiempo de respuesta de tu aplicación está determinado por tu dependencia más lenta—que podría ser infinitamente lenta.

3. Estrategias de Reintento: Cuándo y Cómo Intentar de Nuevo

Los reintentos pueden convertir fallos transitorios en peticiones exitosas. Pero reintentos ingenuos pueden empeorar las cosas.

Cuándo Reintentar

No todos los fallos deberían reintentarse:

flowchart TD
    E[Ocurrió Error] --> S{Código de Estado?}

    S -->|4xx| C4[Error del Cliente]
    S -->|5xx| C5[Error del Servidor]
    S -->|Error de Red| CN[Error de Red]
    S -->|Timeout| CT[Timeout]

    C4 --> D4{Cuál 4xx?}
    D4 -->|400, 401, 403, 404| N1[No Reintentar
Arregla la petición] D4 -->|429| R1[Reintentar
Después de esperar] D4 -->|408| R2[Reintentar
Inmediatamente posible] C5 --> D5{Cuál 5xx?} D5 -->|500| M1[Quizás Reintentar
Bug del servidor?] D5 -->|502, 503, 504| R3[Reintentar
Fallo transitorio] CN --> R4[Reintentar
Red recuperada?] CT --> R5[Reintentar
Pero con cuidado!] style N1 fill:#ffccbc style R1 fill:#c8e6c9 style R2 fill:#c8e6c9 style R3 fill:#c8e6c9 style R4 fill:#c8e6c9 style R5 fill:#fff9c4 style M1 fill:#fff9c4

Seguro para reintentar:

  • 429 Too Many Requests (después de esperar)
  • 502 Bad Gateway
  • 503 Service Unavailable
  • 504 Gateway Timeout
  • Errores de red (conexión rechazada, fallo DNS)
  • Timeouts (con precaución)

No reintentar:

  • 400 Bad Request (tu petición está mal formada)
  • 401 Unauthorized (tus credenciales están mal)
  • 403 Forbidden (no tienes permiso)
  • 404 Not Found (el recurso no existe)
  • 409 Conflict (conflicto de estado, necesita resolución)

Quizás reintentar:

  • 500 Internal Server Error (podría ser un bug transitorio)
  • Timeouts en operaciones no idempotentes (ver sección de idempotencia)

El Problema con Reintentos Ingenuos

Reintentos inmediatos simples pueden causar tormentas de reintentos:

sequenceDiagram
    participant C1 as Cliente 1
    participant C2 as Cliente 2
    participant C3 as Cliente 3
    participant S as Servidor Sobrecargado

    Note over S: Servidor al 100% de capacidad

    C1->>S: Petición 1
    C2->>S: Petición 2
    C3->>S: Petición 3

    S--xC1: 503 Service Unavailable
    S--xC2: 503 Service Unavailable
    S--xC3: 503 Service Unavailable

    Note over C1,C3: Todos los clientes reintentan inmediatamente

    C1->>S: Reintento 1
    C2->>S: Reintento 2
    C3->>S: Reintento 3

    Note over S: Ahora manejando 6 peticiones
en lugar de 3! style S fill:#ffccbc

Cuando todos los clientes reintentan inmediatamente, amplifican la carga en un servidor que ya está luchando.

Backoff Exponencial

La solución es backoff exponencial: Esperar más tiempo entre cada reintento.

Intento 1: Esperar 1 segundo
Intento 2: Esperar 2 segundos
Intento 3: Esperar 4 segundos
Intento 4: Esperar 8 segundos
Intento 5: Esperar 16 segundos
...

La espera crece exponencialmente: delay = base * 2^intento

graph LR
    A1[Intento 1] -->|1s espera| A2[Intento 2]
    A2 -->|2s espera| A3[Intento 3]
    A3 -->|4s espera| A4[Intento 4]
    A4 -->|8s espera| A5[Intento 5]

    style A1 fill:#e3f2fd
    style A2 fill:#bbdefb
    style A3 fill:#90caf9
    style A4 fill:#64b5f6
    style A5 fill:#42a5f5

Esto le da tiempo al servidor para recuperarse mientras previene tormentas de reintentos.

Jitter: Aleatorizando las Esperas

Incluso con backoff exponencial, si 1000 clientes empiezan a reintentar al mismo tiempo, golpearán al servidor en oleadas sincronizadas.

Jitter añade aleatoriedad a la espera:

# Full jitter (recomendado)
delay = random(0, base * 2^intento)

# Decorrelated jitter
delay = random(base, delay_anterior * 3)

En lugar de que todos los clientes esperen exactamente 4 segundos, esperan aleatoriamente entre 0-4 segundos, distribuyendo la carga:

graph LR
    subgraph Sin Jitter
        W1[Cliente A: 4s]
        W2[Cliente B: 4s]
        W3[Cliente C: 4s]
    end

    subgraph Con Jitter
        J1[Cliente A: 1.2s]
        J2[Cliente B: 3.7s]
        J3[Cliente C: 2.4s]
    end

    style W1 fill:#ffccbc
    style W2 fill:#ffccbc
    style W3 fill:#ffccbc
    style J1 fill:#c8e6c9
    style J2 fill:#c8e6c9
    style J3 fill:#c8e6c9

Cuándo NO Reintentar

Nunca reintentar cuando:

  1. La petición tuvo éxito (obviamente, pero verifica idempotencia)
  2. El error es permanente: 400, 401, 403, 404
  3. Has excedido el máximo de reintentos: Saber cuándo rendirse
  4. El timeout ha expirado: No reintentar hasta el infinito
  5. La operación no es segura de repetir: Operaciones no idempotentes sin claves de idempotencia

Ten cuidado cuando:

  1. La operación tiene efectos secundarios: Podría causar duplicados
  2. El timeout fue ambiguo: ¿Tuvo éxito o no?
  3. Estás propagando latencia al usuario: Ellos están esperando

Presupuesto de Reintentos

Establece límites en los reintentos para prevenir bucles infinitos:

  • Máximo de intentos: Limita el total de intentos (ej: 3-5)
  • Tiempo total máximo: Deja de reintentar después de N segundos
  • Presupuesto de reintentos: Solo reintentar X% de las peticiones en una ventana de tiempo

4. Idempotencia: Haciendo los Reintentos Seguros

Ocurre un timeout. ¿Tu pago pasó? No lo sabes. Si reintentas y ya tuvo éxito, podrías cobrarle al cliente dos veces.

La idempotencia hace que las operaciones sean seguras de reintentar.

Qué Es la Idempotencia

Una operación es idempotente si llamarla múltiples veces produce el mismo resultado que llamarla una vez.

graph LR
    subgraph Idempotente
        I1[x = 5] -->|Llamar una vez| IR1[x = 5]
        I2[x = 5] -->|Llamar dos veces| IR2[x = 5]
        I3[x = 5] -->|Llamar N veces| IR3[x = 5]
    end

    subgraph No Idempotente
        N1[x = 0] -->|Llamar una vez| NR1[x = 1]
        N2[x = 0] -->|Llamar dos veces| NR2[x = 2]
        N3[x = 0] -->|Llamar N veces| NR3[x = N]
    end

    style IR1 fill:#c8e6c9
    style IR2 fill:#c8e6c9
    style IR3 fill:#c8e6c9
    style NR1 fill:#fff9c4
    style NR2 fill:#fff9c4
    style NR3 fill:#ffccbc

Operaciones naturalmente idempotentes:

  • GET /users/123 — Leer no cambia nada
  • PUT /users/123 {name: "Alice"} — Establece el mismo estado cada vez
  • DELETE /users/123 — El recurso ya no existe después de la primera llamada

NO naturalmente idempotentes:

  • POST /payments — Cada llamada podría crear un nuevo pago
  • POST /emails/send — Cada llamada podría enviar otro email
  • x = x + 1 — Cada llamada incrementa

Claves de Idempotencia

Para operaciones no idempotentes, usa claves de idempotencia—identificadores únicos que permiten al servidor detectar peticiones duplicadas.

POST /payments HTTP/1.1
Content-Type: application/json
Idempotency-Key: abc123-unique-request-id

{
  "amount": 100,
  "currency": "USD",
  "recipient": "user_456"
}

Cómo funciona:

sequenceDiagram
    participant C as Cliente
    participant S as Servidor
    participant DB as Base de Datos

    C->>S: POST /payments
Idempotency-Key: abc123 S->>DB: Verificar: visto abc123? DB-->>S: No S->>DB: Procesar pago S->>DB: Almacenar: abc123 -> resultado S-->>C: 200 OK, payment_id: 789 Note over C: Red falla, cliente reintenta C->>S: POST /payments
Idempotency-Key: abc123 S->>DB: Verificar: visto abc123? DB-->>S: Sí, resultado existe S-->>C: 200 OK, payment_id: 789 Note over C: Mismo resultado, sin pago duplicado!

Propiedades clave de las claves de idempotencia:

  1. Generadas por el cliente: El cliente crea un ID único antes del primer intento
  2. Almacenadas por el servidor: El servidor recuerda el mapeo clave -> resultado
  3. Devuelve resultado cacheado: En el reintento, el servidor devuelve la respuesta original
  4. Expira eventualmente: Las claves no necesitan vivir para siempre (horas a días)

El Contrato de Idempotencia

Cuando usas una clave de idempotencia:

  • Misma clave + misma petición = mismo resultado
  • Misma clave + diferente petición = error (algunas APIs permiten esto, otras no)
  • El servidor debe completar el almacenamiento antes de responder (o usar transacciones)

Error común: Generar una nueva clave de idempotencia para cada reintento. Eso derrota el propósito—cada reintento parece una nueva petición!

// MAL: Nueva clave para cada intento
async function processPaymentMal(amount) {
  for (let attempt = 0; attempt < 3; attempt++) {
    try {
      const idempotencyKey = generateUUID(); // Nueva clave cada vez!
      return await api.createPayment({ amount, idempotencyKey });
    } catch (error) {
      if (attempt === 2) throw error;
    }
  }
}

// BIEN: Misma clave para todos los intentos
async function processPaymentBien(amount) {
  const idempotencyKey = generateUUID(); // Generar una vez
  for (let attempt = 0; attempt < 3; attempt++) {
    try {
      return await api.createPayment({ amount, idempotencyKey });
    } catch (error) {
      if (attempt === 2) throw error;
    }
  }
}

5. Circuit Breaker: Protegiendo Tu Sistema

Cuando una dependencia está fallando, continuar llamándola desperdicia recursos y puede causar fallos en cascada. El patrón circuit breaker detiene esto.

La Analogía del Circuit Breaker

Piensa en un interruptor de circuito eléctrico en tu casa:

  • Operación normal: La electricidad fluye libremente
  • Sobrecarga detectada: El interruptor salta, corta la energía
  • Reset manual: Después de arreglar el problema, reseteas el interruptor

Un circuit breaker de API funciona de la misma manera:

  • Estado cerrado: Las peticiones pasan normalmente
  • Estado abierto: Las peticiones fallan inmediatamente sin llamar al servicio fallando
  • Estado semi-abierto: Permite algunas peticiones de prueba para verificar si el servicio se recuperó

Estados del Circuit Breaker

stateDiagram-v2
    [*] --> Cerrado

    Cerrado --> Abierto: Umbral de fallos excedido
    Abierto --> SemiAbierto: Timeout expira
    SemiAbierto --> Cerrado: Petición de prueba exitosa
    SemiAbierto --> Abierto: Petición de prueba falla

    note right of Cerrado
        Operación normal
        Contando fallos
    end note

    note right of Abierto
        Fallo rápido
        Sin peticiones enviadas
    end note

    note right of SemiAbierto
        Probando recuperación
        Peticiones limitadas
    end note

Cómo Funciona

Estado Cerrado (normal):

sequenceDiagram
    participant C as Cliente
    participant CB as Circuit Breaker
    participant S as Servicio

    C->>CB: Petición 1
    CB->>S: Reenviar petición
    S-->>CB: Éxito
    CB-->>C: Éxito

    C->>CB: Petición 2
    CB->>S: Reenviar petición
    S--xCB: Fallo (1)
    CB-->>C: Fallo

    C->>CB: Petición 3
    CB->>S: Reenviar petición
    S--xCB: Fallo (2)
    CB-->>C: Fallo

    Note over CB: Conteo de fallos: 2/5

Las peticiones pasan. Los fallos se cuentan. Si los fallos exceden el umbral (ej: 5 fallos en 30 segundos), el circuito se abre.

Estado Abierto (fallando rápido):

sequenceDiagram
    participant C as Cliente
    participant CB as Circuit Breaker
    participant S as Servicio

    Note over CB: Circuito ABIERTO
Servicio asumido caído C->>CB: Petición 1 CB--xC: Falla inmediatamente Note over CB: Sin petición enviada! C->>CB: Petición 2 CB--xC: Falla inmediatamente C->>CB: Petición 3 CB--xC: Falla inmediatamente Note over CB: Esperando timeout...

Ninguna petición llega al servicio fallando. Los clientes obtienen fallos rápidos en lugar de timeouts lentos. El sistema ahorra recursos y evita amplificar el problema.

Estado Semi-Abierto (probando recuperación):

sequenceDiagram
    participant C as Cliente
    participant CB as Circuit Breaker
    participant S as Servicio

    Note over CB: Timeout expirado
Intentar semi-abierto C->>CB: Petición 1 CB->>S: Petición de prueba S-->>CB: Éxito! CB-->>C: Éxito Note over CB: Servicio recuperado!
Circuito CERRADO

Después de un timeout (ej: 30 segundos), el circuit breaker permite una petición de prueba. Si tiene éxito, el circuito se cierra. Si falla, el circuito se abre de nuevo.

Por Qué Importan los Circuit Breakers

Sin un circuit breaker:

graph LR
    subgraph Sin Circuit Breaker
        A[Tu Servicio] -->|100 req/s| B[Servicio Fallando]
        B -->|100 timeouts/s| A
        A -->|Threads agotados| C[Tu Servicio Caído]
    end

    style B fill:#ffccbc
    style C fill:#ffccbc

Con un circuit breaker:

graph LR
    subgraph Con Circuit Breaker
        A[Tu Servicio] -->|Circuito Abierto| CB[Circuit Breaker]
        CB -->|Fallo Rápido| A
        A -->|Degrada elegantemente| D[Tu Servicio Sigue Arriba]
    end

    style D fill:#c8e6c9

Beneficios:

  • Fallo rápido: No desperdiciar tiempo en peticiones condenadas
  • Proteger recursos: No agotar pools de threads/conexiones
  • Permitir recuperación: Dar al servicio fallando espacio para respirar
  • Prevenir fallos en cascada: Tu fallo no se convierte en el fallo de todos

Configuración del Circuit Breaker

Parámetros clave:

ParámetroDescripciónValor Típico
Umbral de fallosFallos para abrir circuito5-10 fallos
Ventana de tiempoPeríodo para contar fallos30-60 segundos
Timeout abiertoCuánto tiempo permanece abierto30-60 segundos
Peticiones semi-abiertasPeticiones de prueba permitidas1-3

6. Degradación Elegante: Fallando Bien

Cuando una dependencia falla, tienes opciones más allá de “error” o “éxito.” Degradación elegante significa proporcionar funcionalidad reducida en lugar de fallo completo.

Estrategias de Degradación

Devolver datos cacheados:

Cuando la API de productos está caída, devolver datos cacheados obsoletos con una advertencia.

{
  "products": [...],
  "metadata": {
    "cached": true,
    "cachedAt": "2026-01-12T10:00:00Z",
    "warning": "Los datos pueden estar desactualizados"
  }
}

Devolver valores por defecto:

Cuando el servicio de personalización está caído, mostrar recomendaciones genéricas.

{
  "recommendations": ["popular-item-1", "popular-item-2"],
  "personalized": false
}

Reducir funcionalidad:

Cuando el procesamiento de pagos está lento, deshabilitar checkout pero mantener la navegación funcionando.

Encolar para después:

Cuando el servicio de email está caído, encolar emails y enviarlos cuando el servicio se recupere.

Árbol de Decisión de Degradación

flowchart TD
    F[Dependencia Falló] --> Q1{Crítico para
esta operación?} Q1 -->|No| S1[Omitirlo
Continuar sin él] Q1 -->|Sí| Q2{Tienes datos cacheados?} Q2 -->|Sí| S2[Devolver cacheado
con advertencia] Q2 -->|No| Q3{Tienes valor por defecto?} Q3 -->|Sí| S3[Devolver por defecto
con advertencia] Q3 -->|No| Q4{Puedes encolar para después?} Q4 -->|Sí| S4[Encolar y
confirmar recepción] Q4 -->|No| S5[Devolver error
elegantemente] style S1 fill:#c8e6c9 style S2 fill:#c8e6c9 style S3 fill:#fff9c4 style S4 fill:#fff9c4 style S5 fill:#ffccbc

Ejemplos de Degradación Elegante

Sitio de e-commerce:

CaracterísticaEstado DegradadoExperiencia de Usuario
Búsqueda de productosMostrar resultados cacheados“Los resultados pueden estar desactualizados”
RecomendacionesMostrar items popularesMenos personalizado pero funcional
ReseñasOcultar sección de reseñasPágina de producto aún funciona
PagoMostrar “intenta más tarde”No puede comprar, pero puede navegar

Red social:

CaracterísticaEstado DegradadoExperiencia de Usuario
TimelineMostrar posts cacheados“Mostrando posts recientes”
Contador de likesOcultar contadoresAún puede dar like
ComentariosDeshabilitar nuevos comentariosPuede leer existentes
NotificacionesAgrupar y retrasarPequeño retraso aceptable

El Principio Clave

Siempre pregunta: “¿Cuál es la mejor experiencia que puedo proporcionar cuando esto falla?”

La respuesta raramente es “mostrar una página de error.” Usualmente hay una experiencia parcial que es mejor que nada.

7. Juntando Todo

Así es como estos conceptos funcionan juntos en un sistema resiliente:

flowchart TD
    R[Petición] --> T{Timeout
configurado?} T -->|No| WARN[Agregar timeout!] T -->|Sí| CB{Estado del
circuit breaker?} CB -->|Abierto| FF[Fallo rápido] CB -->|Cerrado/Semi-Abierto| S[Enviar petición] S --> RESULT{Resultado?} RESULT -->|Éxito| REC[Registrar éxito] RESULT -->|Fallo| CHK{Reintentar?} CHK -->|No| FINAL[Devolver error] CHK -->|Sí| IK{Idempotente/
tiene clave?} IK -->|No| DANGER[Peligroso reintentar!] IK -->|Sí| LIMIT{Bajo límite
de reintentos?} LIMIT -->|No| GIVEUP[Rendirse] LIMIT -->|Sí| WAIT[Backoff + jitter] WAIT --> CB REC --> CLOSE[Circuito permanece/se cierra] FINAL --> COUNT[Contar fallo] COUNT --> THRESH{Umbral
excedido?} THRESH -->|Sí| OPEN[Abrir circuito] THRESH -->|No| DONE[Listo] FF --> DEGRADE{Puede degradar
elegantemente?} DEGRADE -->|Sí| CACHED[Devolver cacheado/defecto] DEGRADE -->|No| ERROR[Devolver error] style WARN fill:#ffccbc style DANGER fill:#ffccbc style FF fill:#fff9c4 style CACHED fill:#c8e6c9

Resumen de Patrones de Resiliencia

ProblemaSoluciónConcepto Clave
Respuestas lentasTimeoutsTiempo de espera acotado
Fallos transitoriosReintentosIntentar de nuevo
Tormentas de reintentosBackoff exponencialEsperar más cada vez
Reintentos sincronizadosJitterAleatorizar esperas
Operaciones duplicadasClaves de idempotenciaMisma entrada = misma salida
Fallos en cascadaCircuit breakerFallo rápido cuando dependencia caída
Fallo totalDegradación eleganteMejor experiencia posible

Qué Sigue

Esta guía cubrió los conceptos de resiliencia—entender por qué las cosas fallan y los patrones que ayudan.

Para detalles de implementación incluyendo:

  • Configuración de timeouts para diferentes escenarios
  • Ajuste de parámetros de reintentos para tu caso de uso
  • Implementación de almacenamiento de claves de idempotencia
  • Configuración de umbrales de circuit breaker
  • Métricas, alertas y observabilidad para fallos

Consulta el próximo curso: Resiliencia y tolerancia a fallos en APIs REST.


Términos Relacionados del Vocabulario

Profundiza tu entendimiento con estos conceptos relacionados: