Episodio 2 · 11:00

Compartimentos estancos

lectura · 12 mindominio · BCPS Bankoperación · pago con tarjeta y bloqueo

El doble de pagos

A las once, el tráfico de Black Friday se ha duplicado. Tarjetas ya tiene timeouts, como aprendimos a las diez: si Antifraude no contesta en 3 segundos, no se le espera más. Y aun así, cuando Antifraude vuelve a ir lento, Luis vuelve a no poder bloquear su tarjeta.

El timeout limita cuánto espera cada pago, pero no cuántos esperan a la vez. Con doce pagos por segundo esperando tres segundos cada uno, hacen falta 36 conexiones solo para esperar a Antifraude. Tarjetas tiene 24.

Los barcos resolvieron esto hace siglos: dividen el casco en compartimentos estancos. Si entra agua en uno, se inunda ese, y el barco sigue a flote. En software se llama bulkhead, que es precisamente el nombre de esos mamparos.

Un pool o tres

Tarjetas atiende tres cosas: llamadas a Antifraude, llamadas a Cuentas y bloqueos de tarjeta. A la izquierda, las 24 conexiones son de todos y cada pago se queda la suya de principio a fin. A la derecha, las mismas 24 repartidas: 12 para Antifraude, 8 para Cuentas y 4 para bloqueos.

Si Antifraude no contesta, o no hay sitio para llamarle, Tarjetas autoriza con riesgo acotado: hasta 50 € por pago y 150 € por tarjeta; lo que pase de ahí se deniega. Pon Antifraude lento y pulsa L cuando la cola del pool compartido crezca.

Qué ha pasado

El pool compartido es un punto de contagio

Con Antifraude lento, cada pago retiene su conexión tres segundos y las 24 se llenan enseguida.probar en el laboratorio A partir de ahí da igual qué pida cada petición: todas hacen la misma cola. El bloqueo de Luis, que tarda 60 milisegundos y no toca Antifraude, espera detrás de pagos que esperan a Antifraude, y la app se rinde.

Es el mismo fallo en cascada del episodio 1, pero ahora con timeouts. El timeout acota cuánto dura cada espera; con tráfico suficiente, las esperas acotadas también llenan el pool. Lo que falta es acotar cuántas peticiones pueden estar esperando a una misma dependencia.

En este episodio Tarjetas no propaga el plazo del TPV, para ver solo el efecto de los compartimentos. Con plazo, el pool compartido se degrada de otra forma: los pagos siguen haciendo cola, pero llegan a Antifraude sin tiempo para esperarle. Tampoco es bueno: todos esperan casi 5 s y casi nadie recibe una respuesta de verdad.

Un compartimento por dependencia

Con compartimentos, cada dependencia tiene un número máximo de llamadas en curso. Cuando Antifraude va lento, se llena su compartimento de 12, y ahí se queda el problema:

Fíjate en lo que ha pasado con los pagos. En el pool compartido, casi todos acaban fallidos: el TPV se cansa de esperar. Con compartimentos, muchos se deniegan. No es lo mismo. Un fallido es una avería: nadie ha decidido nada, y ni la tienda ni Ana saben qué ha pasado. Un denegado es una decisión del banco («sin Antifraude, no autorizo más de 50 €»), tomada rápido y con un motivo.

Con Cuentas lento

Si el lento es Cuentas, el pool compartido se atasca igual.probar en el laboratorio Con compartimentos, se llena el de Cuentas y los pagos que no caben fallan al momento. Aquí no hay alternativa razonable: sin retención no se puede autorizar. Pero fallan en milisegundos y no en cinco segundos, y los bloqueos siguen funcionando.

Hay un detalle honesto: con compartimentos se autorizan algo menos pagos que con el pool compartido. El compartimento limita a 8 los pagos que esperan a Cuentas a la vez, y sin él había hasta 24. Aislar tiene ese precio: renuncias a usar capacidad libre de otro sitio para contener el daño.

Cuándo hace daño: compartimentos mal repartidos

Repartir mal es fácil. Deja 2 conexiones a Antifraude, 2 a Cuentas y 20 a los bloqueos, con todo sano.probar en el laboratorio El pico normal de Black Friday ya no cabe en el compartimento de Antifraude, y los pagos que sobran van a riesgo acotado aunque Antifraude esté perfectamente: se deniegan compras que Antifraude habría aprobado. En el de Cuentas no cabe ni lo autorizado, y falla. Mientras tanto, 20 conexiones para bloqueos sin usar.

El pool compartido, con las mismas 24 conexiones, no tiene ese problema: cada petición usa la que esté libre. Esa es la contrapartida de los compartimentos: la capacidad que sobra en uno no se puede prestar a otro. Hay que dimensionarlos con datos (cuántas llamadas en curso tiene cada dependencia en el pico normal, con margen) y revisarlos cuando cambia el tráfico.

Y Notificaciones ni siquiera está en la foto

Tarjetas también avisa a Ana de cada pago, pero Notificaciones no aparece en la simulación. No es un olvido: Tarjetas publica PagoAutorizado y sigue, sin esperar a nadie. Como vimos en el episodio 1 de la serie de eventos, comunicarse por eventos es la forma más barata de aislar un servicio: si Notificaciones va lento, se le acumulan los eventos, y Tarjetas no gasta ni una conexión en ello. Los compartimentos son para lo que no puede ir por eventos, como preguntar a Antifraude antes de autorizar.

Criterio

SituaciónQué hacerEn BCPS Bank
Un servicio llama a varias dependencias síncronasUn compartimento (pool o semáforo) por dependenciaTarjetas: uno para Antifraude y otro para Cuentas
Hay operaciones críticas que no dependen de lo lentoUn compartimento propio, aunque sea pequeñoLos bloqueos de tarjeta
El compartimento de una dependencia está llenoNo esperar: responder ya con la alternativa, o fallar rápidoRiesgo acotado si falta Antifraude; fallido si falta Cuentas
La dependencia puede ir por eventosMejor eso que un compartimentoNotificaciones
Servicio pequeño, una sola dependencia, tráfico modestoUn pool compartido basta: los compartimentos añaden números que mantener—

Para dimensionar cada compartimento: llamadas por segundo en el pico × lo que tarda cada una cuando va bien (su p99), más margen. Con 12 pagos por segundo y Antifraude a 150 ms, bastan 2 o 3 en uso medio; 12 dejan sitio para picos y para que Antifraude vaya algo lento sin que salte el riesgo acotado.

En el mundo real

El nombre lo popularizó Michael Nygard en Release It!, y Netflix lo llevó a la práctica en Hystrix, que ejecutaba cada dependencia en su propio pool de hilos (o detrás de un semáforo). Hystrix está en mantenimiento desde 2018; hoy en Java se usa Resilience4j, que ofrece Bulkhead (semáforo) y ThreadPoolBulkhead.

En las mallas de servicios, Envoy limita las conexiones y peticiones pendientes por clúster de destino (circuit breaking, en su terminología, aunque funciona como un compartimento): cuando se llena, rechaza al momento en vez de encolar.

La misma idea aparece a mayor escala: servicios separados por tipo de cliente (la API interna y la pública en máquinas distintas), cell-based architecture (AWS reparte a sus clientes en celdas independientes, para que un fallo afecte solo a una parte) o shuffle sharding, que asigna a cada cliente una combinación distinta de servidores para que un cliente problemático no arrastre a otro.

Siguiente episodio

Hasta ahora Antifraude iba lento. A mediodía se cae del todo, treinta segundos. Cada instancia de Tarjetas hace lo que haría cualquiera: volver a intentarlo. El problema es que son muchas, y todas a la vez.

Siguiente · Episodio 3 · 12:00 Reintentar sin empeorarlo Reintentos, backoff exponencial y jitter: cómo convertir una caída de 30 segundos en una de minutos, y cómo evitarlo.

← Todos los episodios · Mapa de BCPS Bank