Reintentar sin empeorarlo
Treinta segundos que duraron un minuto y medio
A las 12:00:03, Antifraude se cuelga. Un segundo después, su proceso muere y el orquestador lo reinicia: treinta segundos hasta que vuelve a arrancar. Una caída corta, de las que pasan.
Pero Antifraude no vuelve. Arranca, aguanta un segundo y se cae otra vez. Y otra. El equipo de Antifraude jura que su servicio está bien: cuando lo prueban aislado, funciona. Lo que lo tumba es lo que le llega nada más arrancar.
Lo que le llega son reintentos. Reintentar es lo más razonable del mundo cuando una llamada falla: la mayoría de los fallos son pasajeros. El problema es que Antifraude no tiene un cliente, tiene cuatro instancias de Tarjetas con cinco trabajadores cada una, y todos piensan lo mismo a la vez.
Veinte clientes impacientes
Cuatro instancias de Tarjetas reciben 24 pagos por segundo y llaman a Antifraude, que aguanta 50 por segundo. Si una llamada falla, se reintenta hasta tres veces; si los tres intentos fallan, el pago pasa a riesgo acotado. A la izquierda, los reintentos son inmediatos. A la derecha, con backoff exponencial: se espera 1 s y luego 2 s.
Antifraude arranca en frío: al volver solo aguanta el 40 % y tarda diez segundos en calentar. Si en una décima de segundo le llega el triple de lo que aguanta, se vuelve a caer. Pulsa Arrancar, tira Antifraude y mira el minigráfico de cada panel. Luego prueba con jitter.
Qué ha pasado
El reintento inmediato, cuando el problema es la carga
Reintentar en el acto funciona si el fallo es un error suelto: un paquete perdido, una conexión que se cerró justo entonces. Pero cuando falla porque el servicio está sobrecargado o arrancando, reintentar en el acto es mandarle más trabajo justo cuando menos puede con él.probar en el laboratorio
Mira lo que pasa cuando Antifraude vuelve. Arranca aguantando 20 llamadas por segundo y le llegan 24 pagos. Rechaza unos pocos, y cada rechazo se convierte en dos llamadas más en el mismo instante. En menos de un segundo le llega el triple de lo que aguanta y se vuelve a caer. Eso es una tormenta de reintentos (retry storm): los reintentos no solo no ayudan, sino que son lo que impide que el servicio se recupere.
Backoff: esperar más cada vez
La primera idea es esperar entre intentos, y esperar más cuanto más fallas: 1 s, luego 2 s, luego 4 s. Es el backoff exponencial. Si el servicio está sobrecargado, cada cliente se aparta un poco más, y la carga total baja justo cuando hace falta. En la simulación se nota en dos sitios: hay menos llamadas por pago, y los trabajadores de Tarjetas pasan el rato esperando (las casillas naranjas) en lugar de llamar.
Pero fíjate en el minigráfico del backoff sin jitter.probar en el laboratorio La carga no es una línea, son picos. Cuando Antifraude murió, las veinte llamadas que tenía colgadas fallaron en el mismo instante. Los veinte trabajadores esperaron exactamente 1 segundo, llamaron a la vez, esperaron exactamente 2, llamaron a la vez… Siguen sincronizados, solo que más espaciados. Y cuando Antifraude vuelve, le llega uno de esos picos de golpe: veinte llamadas en una décima de segundo a un servicio que aguanta dos. Se cae, las llamadas en curso fallan a la vez, y los trabajadores quedan sincronizados otra vez.
Jitter: que cada uno espere distinto
La solución es añadir azar a la espera: el jitter. En la simulación, cada trabajador espera la mitad del backoff más una parte al azar de la otra mitad: entre 0,5 y 1 s, luego entre 1 y 2 s.probar en el laboratorio Basta con eso para que los veinte trabajadores dejen de estar en fase: después de un par de reintentos, sus llamadas llegan repartidas y el minigráfico se aplana. Antifraude arranca, recibe una carga que puede asumir, calienta y se queda.
La misma caída de 30 segundos cuesta muy distinto según cómo se reintente. Mira el contador «Antifraude caído» de cada panel: es la parte del día en la que todos los pagos grandes se deniegan por riesgo acotado.
Hay varias formas de jitter. La «completa» espera un tiempo al azar entre cero y el backoff: reparte mejor, pero de media espera la mitad. La de la simulación («a medias») garantiza una espera mínima. Lo importante no es la fórmula exacta, sino que dos clientes que fallaron a la vez no vuelvan a la vez.
Amplificación por capas
Tarjetas no es el único que reintenta. Si el TPV, al recibir un error, también reintenta, y lo hace tres veces, cada pago puede acabar en 3 × 3 = 9 llamadas a Antifraude.probar en el laboratorio Con una capa más (la app que llama al TPV, un balanceador que reintenta por su cuenta) serían 27. Cada capa hace lo razonable desde su punto de vista, y el total es una locura.
La regla es reintentar en una sola capa, normalmente la más cercana al fallo, y que las demás no lo hagan (o que sepan que abajo ya se ha reintentado). Algunos sistemas mandan una cabecera para decir «esto ya es un reintento, no reintentes tú».
Cuándo hace daño: reintentar lo que no es idempotente
Hasta aquí los reintentos eran a Antifraude, que solo evalúa un riesgo: llamarle dos veces no cambia nada. Pero el reintento del TPV no es a Antifraude, es a autorizar el pago, y eso aplica una retención en la cuenta de Ana.
Imagina que el TPV manda la autorización, Tarjetas la procesa y aplica la retención, pero la respuesta se pierde. El TPV no sabe si ha ido bien y reintenta. Si Tarjetas lo ve como un pago nuevo, aplica una segunda retención: Ana tiene 76 € retenidos por una compra de 38. Es exactamente el duplicado de la transferencia de Ana en la serie de eventos, y la solución es la misma: un identificador de autorización estable que el TPV reutiliza en cada reintento, y que Tarjetas recuerda para devolver la misma respuesta sin repetir nada (episodio 4 de eventos).
Criterio
Reintentar está bien. Reintentar bien tiene cinco condiciones:
| Condición | Por qué | En BCPS Bank |
|---|---|---|
| Solo lo idempotente | Si no, cada reintento puede duplicar el efecto | Antifraude, sí; autorizar, solo con id estable |
| En una sola capa | Los reintentos de cada capa se multiplican | Reintenta Tarjetas; el TPV, no |
| Con backoff | Si el problema es la carga, hay que quitar carga | 1 s, 2 s |
| Con jitter | Los clientes que fallan a la vez no deben volver a la vez | Espera en parte al azar |
| Con un tope | De intentos y de tiempo: dentro del plazo de quien espera | 3 intentos, dentro de los 5 s del TPV |
Y una pregunta previa: ¿tiene sentido reintentar este error? Un timeout o un 503 sí; un «importe no válido» o un 403, no: va a fallar igual. Si el servicio manda Retry-After, respétalo.
Aun así, si Antifraude lleva un minuto caído, cada pago sigue gastando sus tres intentos y su espera antes de ir a riesgo acotado. Reintentar con cuidado reduce el daño, pero no evita llamar a algo que sabemos que no va a contestar. Eso es el siguiente episodio.
En el mundo real
El artículo de referencia es «Exponential Backoff And Jitter», de Marc Brooker en el blog de arquitectura de AWS, que compara varias fórmulas de jitter con simulaciones parecidas a esta. Los SDK de AWS aplican backoff con jitter por defecto y, además, un retry budget: un cupo de reintentos por cliente que, si se agota, deja de reintentar hasta que las llamadas vuelvan a ir bien.
gRPC permite configurar la política de reintentos por método (intentos, backoff inicial, multiplicador, códigos reintentables) y limita los reintentos cuando detecta que muchos fallan. Envoy tiene retry_policy por ruta y un límite de reintentos simultáneos por clúster, precisamente para que una malla de servicios no amplifique una caída.
Las caídas largas por tormentas de reintentos son un clásico de los informes post mortem: un servicio que vuelve y lo tumban sus propios clientes. La otra cara del problema, el «rebaño» de clientes que vuelve a la vez (thundering herd), aparece también con cachés que caducan todas a la vez o con clientes móviles que se reconectan al mismo tiempo tras un corte.
Siguiente episodio
A la una, Antifraude se cae otra vez, y esta vez no vuelve en treinta segundos. Cada pago sigue probando suerte con él antes de rendirse: tiempo perdido y carga para un servicio que no va a contestar. ¿Y si Tarjetas dejara de llamarle durante un rato?
Siguiente · Episodio 4 · 13:00 Dejar de llamar El circuit breaker: cerrado, abierto y semiabierto. Y el riesgo acotado como decisión de negocio.