Episodio 1 · 10:00

Un servicio lento lo tumba todo

lectura · 13 mindominio · BCPS Bankoperación · pago con tarjeta

Black Friday, diez de la mañana

Las tiendas acaban de abrir y los pagos con tarjeta de BCPS Bank se multiplican. Ana va de compras. Luis, en cambio, lleva media hora buscando su cartera: la ha perdido y quiere bloquear la tarjeta desde la app antes de que alguien la use.

A las 10:00, Antifraude empieza a ir lento. No se ha caído: contesta, pero en ocho segundos en vez de en ochenta milisegundos. Nadie lo ha notado todavía, porque no hay ninguna alarma de «caído».

Cinco minutos después, Luis pulsa «Bloquear tarjeta» y la app le dice que lo intente más tarde. Bloquear una tarjeta no pasa por Antifraude. ¿Qué tiene que ver una cosa con la otra?

Pagos sin parar

Los TPV de las tiendas mandan cinco pagos por segundo a Tarjetas, que para autorizar cada uno pregunta a Antifraude y luego pide a Cuentas que retenga el importe. Tarjetas atiende todo con 28 conexiones: son las casillas de su caja. El TPV corta a los 5 segundos.

A la izquierda, cada llamada tiene su propio timeout. A la derecha, además, el plazo del TPV viaja con la petición. Pulsa Arrancar, pon Antifraude lento y mira las casillas. Luego haz que Luis bloquee su tarjeta.

Qué ha pasado

Un fallo en cascada

Con Antifraude lento y sin timeout, cada pago se queda con su conexión de Tarjetas mientras espera la respuesta: ocho segundos en vez de una décima.probar en el laboratorio Llegan cinco pagos por segundo y las 28 conexiones solo dan para despachar tres y medio, así que en unos segundos están todas ocupadas y los pagos nuevos hacen cola.

Luis no compite con los pagos por Antifraude. Compite por algo más escondido: una conexión libre de Tarjetas. Su bloqueo se pone a la cola detrás de pagos que esperan a Antifraude, y a los cinco segundos la app se rinde. Eso es un fallo en cascada: el problema de un servicio se contagia a quien le llama, y desde ahí a todo lo que ese servicio atiende, dependa o no del primero.

Fíjate además en el color de las casillas. Las rojas son conexiones que trabajan para un TPV que ya ha mostrado «pago fallido» y se ha olvidado del asunto. Tarjetas no lo sabe y sigue esperando a Antifraude por un pago que ya no le importa a nadie. Es trabajo tirado, y ocupa el sitio del trabajo útil.

Timeout en cada llamada

La primera defensa es no esperar para siempre. Con un timeout de 1 segundo en la llamada a Antifraude, cada pago suelta su conexión como mucho al segundo.probar en el laboratorio Los pagos siguen fallando (Antifraude no contesta a tiempo), pero fallan rápido, las conexiones se vacían y Luis bloquea su tarjeta sin problema.

Es la idea central de toda la serie: no se puede evitar que Antifraude vaya lento, pero sí decidir hasta dónde llega el problema. El timeout lo deja dentro de los pagos, que ya iban a fallar, y protege lo demás.

Timeouts mal escalonados: la retención huérfana

Poner timeout no basta: tiene que ser el adecuado. Supón que el TPV corta a los 5 segundos y Tarjetas espera a Antifraude hasta 10.probar en el laboratorio Antifraude contesta a los 8 segundos, Tarjetas sigue adelante, Cuentas retiene el importe… y la respuesta llega a un TPV que hace tres segundos que le dijo a Ana «pago fallido».

Ana ve en su app 60 € retenidos por una compra que no ha hecho. Se liberarán solos cuando la retención caduque, porque ninguna tienda la confirmará, pero hasta entonces es dinero que no puede gastar y una llamada al banco para preguntar qué ha pasado. A esto lo llamamos autorización huérfana: un efecto que se completa cuando quien lo pidió ya se ha ido.

La regla es que los timeouts se acortan hacia dentro: si el TPV espera 5 s, Tarjetas no puede esperar 10 a nadie. Y como Tarjetas todavía tiene que hablar con Cuentas y contestar, lo que puede esperar a Antifraude es algo menos de 5 s.

El plazo propagado

Calcular esos números a mano en cada salto es frágil: basta con que alguien suba el timeout del TPV o añada un salto intermedio. La alternativa es que el plazo viaje con la petición. El TPV no dice «espero 5 s», sino «necesito la respuesta antes de las 10:00:05». Cada salto mira cuánto queda, reserva lo que necesita para lo que viene después y usa el resto como timeout.

En el panel de la derecha, Tarjetas hace dos cosas con ese plazo:

El plazo acota, pero no hace milagros: si Antifraude tarda siempre más que el plazo, todos los pagos siguen fallando, solo que sin dejar basura. Y si llega mucho más tráfico, también se llenan las conexiones. El timeout corto y el plazo se complementan.

Cuándo hace daño: el timeout demasiado corto

Si los timeouts cortos son tan buenos, ¿por qué no poner 300 ms en todas partes? Prueba con Antifraude «algo lento»: la mayoría de las llamadas tarda 150 ms, pero una de cada cien pasa del segundo.probar en el laboratorio Con 300 ms, alrededor de uno de cada diez pagos falla, y todos se habrían autorizado esperando un poco más. El TPV tenía 5 s; Tarjetas ha decidido rendirse por su cuenta con 4,7 s de margen.

Un timeout demasiado corto convierte la cola lenta de la latencia (esas llamadas del p99) en fallos. Y si además alguien reintenta esos fallos, añade carga justo cuando el servicio va lento, que es el tema del episodio 3. El timeout se elige mirando la latencia real del servicio, no un número redondo.

Criterio

  1. ¿La llamada sale de tu proceso (red, base de datos, otro servicio)?Cualquier cosa que pueda no contestar.
    timeout, siempre
  2. ¿Cuánto debe valer?Por encima del p99 (o p99,9) de lo que tarda ese servicio cuando va bien, y por debajo de lo que espera quien te llama.
    p99 < timeout < el de arriba
  3. ¿Hay más de un salto en la cadena?TPV → Tarjetas → Antifraude ya son dos.
    propaga el plazo

Y dos comprobaciones rápidas para cualquier servicio:

En el mundo real

Valores por defecto peligrosos. La librería requests de Python no pone timeout si no se lo pides, y en Java HttpURLConnection espera indefinidamente por defecto. Muchos pools de conexiones de base de datos esperan una conexión libre durante 30 s o más antes de rendirse. Revisarlos es de las tareas más baratas y rentables en resiliencia.

Plazos propagados. gRPC trabaja con deadlines en lugar de timeouts: el cliente fija un instante límite, viaja con la llamada y el servidor puede consultarlo y pasárselo a sus propias llamadas (en Go, a través de context.Context). En HTTP no hay un estándar; se suele mandar el plazo restante en una cabecera propia y cada servicio la respeta y la reenvía.

Mallas de servicios. Envoy (y con él Istio) permite fijar timeouts por ruta y por reintento fuera del código del servicio, lo que ayuda a que no haya ninguna llamada sin timeout, aunque no sustituye a que el código sepa qué hacer cuando salta.

El vocabulario de esta serie (timeouts, bulkheads, circuit breakers) lo popularizó Michael Nygard en Release It!, con historias de sistemas caídos por una sola dependencia lenta. Y el artículo «Timeouts, retries, and backoff with jitter» de la Amazon Builders' Library cuenta cómo elige Amazon sus timeouts a partir de percentiles de latencia.

Siguiente episodio

Con un timeout corto, Luis puede bloquear su tarjeta, pero hemos tenido suerte: Antifraude lento solo consume conexiones un segundo por pago. ¿Y si a las once, con el doble de tráfico, ni siquiera eso basta? Hay una idea más vieja que la informática para que una vía de agua no hunda el barco.

Siguiente · Episodio 2 · 11:00 Compartimentos estancos Un pool por dependencia: cuando Antifraude se atasca, se llena su compartimento y el resto del barco sigue a flote.

← Todos los episodios · Mapa de BCPS Bank