Adrian RomoAdrian Romo
Todos los textos
Nota diaria 1 min de lectura· caffeinated

Nota diaria: Depurando un flujo de API en producción

La prueba de integración pasó, el entorno de staging está en verde, pero en producción falla para el 1% de los llamadores. El error estaba en un lugar que nunca habría adivinado.

Hoy fue uno de esos días.

La API devuelve 200 en staging, 500 para ~1% del tráfico en producción. CloudWatch muestra que la Lambda se está agotando en 29.9s. Todas las pruebas de integración pasaron. Todas las pruebas de carga pasaron.

Pasé dos horas culpando a la base de datos. No era la base de datos.

Resultó que: una de nuestras integraciones SaaS de upstream comenzó a devolver respuestas con un encabezado específico en el que nuestro cliente HTTP intentó reintentar silenciosamente. Tres reintentos × 10s de retroceso = 30s = tiempo de espera de la Lambda. El 1% era el subconjunto de clientes cuyos datos casualmente pasaban por un edge de un proveedor específico.

# antes
session = requests.Session()
session.mount("https://", HTTPAdapter(max_retries=Retry(total=3, backoff_factor=1)))

# después
session = requests.Session()
session.mount("https://", HTTPAdapter(max_retries=Retry(
    total=3,
    backoff_factor=1,
    respect_retry_after_header=False,  # el proveedor miente
    allowed_methods=frozenset(["GET"]),  # nunca reintentar POSTs
)))
python

Lección que sigo reaprendiendo: las políticas de reintento son un límite del sistema. Los valores predeterminados casi siempre son incorrectos para tu sistema.

Me voy a la cama con dolor de cabeza pero con un tablero verde.

Continúa

¿A dónde sigues?

Explora más textos técnicos, revisa los casos de estudio o escríbeme directo.