Patrones de Resiliencia en Microservicios y Agentes Autónomos: Circuit Breakers, Outbox y Consistenc
Diseño de sistemas distribuidos que sobreviven a fallos en cascada, escrituras duales y latencia de agentes autónomos. Implementación real con trade-offs medibles.

Moxi-solutions

Por qué los agentes autónomos rompen las suposiciones de resiliencia clásica
Los agentes autónomos no siguen patrones de tráfico predecibles. Un agente que decide reintentar una tarea fallida puede generar ráfagas de peticiones idénticas en milisegundos, saturando colas y agotando conexiones. Además, su lógica de decisión a menudo depende de estado distribuido, lo que amplifica el impacto de cualquier inconsistencia. Aquí no basta con timeouts: se necesitan mecanismos que corten la propagación del fallo y garanticen la durabilidad de las intenciones del agente.
Circuit Breaker: no es solo un interruptor, es un regulador de presión
El patrón Circuit Breaker evita que un servicio degradado reciba más carga, pero su diseño en entornos con agentes exige ajustes no obvios. La configuración típica de Resilience4j usa una ventana deslizante de 10 segundos, umbral de error del 50% y 5 llamadas mínimas. Sin embargo, los agentes pueden emitir ráfagas que distorsionan la ventana: un pico de 100 errores en 1 segundo dispara el breaker, pero si el servicio ya se recuperó, estás bloqueando tráfico legítimo. La solución es usar ventanas deslizantes por tiempo y no por conteo, combinadas con un umbral de error basado en percentiles, no en promedio. Además, el estado half-open debe permitir solo 1-3 peticiones de prueba, pero para agentes es crítico que esas peticiones sean idempotentes: si el agente reintenta una operación que ya se ejecutó parcialmente, el half-open debe rechazarla sin efectos secundarios.
Outbox: la única forma de no perder eventos en escrituras duales
Cuando un agente autónomo persiste una decisión en su base de datos y necesita emitir un evento (por ejemplo, "Tarea completada"), el patrón naive de escribir en la BD y luego publicar en Kafka falla: el proceso puede morir entre ambas operaciones. El patrón Outbox resuelve esto escribiendo el evento en la misma transacción de la BD y luego publicándolo mediante un proceso separado. Dos implementaciones dominan: polling publisher (un job consulta la tabla outbox cada 500ms-1s y publica) y Change Data Capture (CDC) con Debezium, que lee el WAL de PostgreSQL o binlog de MySQL y publica en tiempo real. El trade-off es latencia vs infraestructura: polling agrega hasta 1 segundo de retraso, CDC es casi instantáneo pero requiere mantener conectores y manejar fallos de replicación. Para agentes, recomendamos CDC si el presupuesto de latencia es <100ms; de lo contrario, polling con un índice por cola de procesamiento y reintentos exponenciales.
Consistencia eventual: diseñar para el desorden y la duplicación
Los eventos del outbox llegan a otros microservicios fuera de orden o duplicados. Los agentes que actúan sobre estos eventos deben implementar idempotencia estricta: cada mensaje lleva un `event_id` único y el consumidor mantiene una tabla de procesados con clave primaria en ese ID. Si llega un duplicado, se ignora. Para el orden, no asumas orden total: usa versiones de entidad o timestamps de evento para resolver conflictos. En flujos con múltiples pasos (sagas), el patrón Saga orquestada con compensación es imprescindible: si un agente inicia una transacción distribuida y un paso falla, se emiten eventos de compensación que revierten los pasos anteriores. La consistencia eventual exige monitorear la latencia de convergencia: métricas como `time_to_consistency` te dirán si tu sistema está tardando demasiado en reflejar la realidad.
Métricas de producción que importan
No basta con implementar los patrones; necesitas observarlos bajo carga real. Tres métricas críticas:
Conclusión
Combinar Circuit Breaker, Outbox y Consistencia Eventual no es opcional cuando despliegas agentes autónomos. Cada patrón resuelve una clase específica de fallo: el breaker corta la propagación, el outbox garantiza la entrega, y la consistencia eventual define el contrato de datos. Sin estos cimientos, cualquier agente con un poco de autonomía se convierte en un vector de fallos en cascada.
¿Te gustó este artículo?
Compártelo con tu red o con un colega que pueda encontrarlo útil.
