Cómo construir un procesamiento seguro de fail millones de transacciones por día
Texto completo del artículo
1) Qué significa fail-safe para las transacciones
Fail-safe es cuando cualquier situación de destrucción conduce a una parada segura o a una condición compensable sin pérdida de dinero y datos. Objetivos:- «Doble débito/crédito» = 0.
- Transacciones/eventos perdidos = 0.
- SLO predecibles por latencia/entrega, modos claros de degradación y DR.
La base son los invariantes monetarios (la verdad del equilibrio en un lugar), la idempotencia, la entrega concertada de los acontecimientos.
2) Principios arquitectónicos (corto)
1. Fuente única de la verdad: balance y contabilidad - en Ledger/Wallet. Los servicios alrededor mantienen los estados de los procesos, no el dinero.
2. Idempotency everywhere: todas las operaciones de «grabación» aceptan 'Idempotency-Key'; la repetición devuelve el mismo resultado.
3. Evento con garantía de entrega: outbox/CDC, colas, DLQ, dedoop.
4. Sagas y compensaciones, no «revisiones manuales».
5. Retroceso y prioridades: el sistema se ralentiza, pero no se derrumba.
6. Observabilidad predeterminada: registros estructurados, treysing, métricas.
7. Multi-región y DR: activo-activo/activo-pasivo, ejercicios regulares.
3) Topología de referencia
Edge/API GW ──Command API ──App Service (Sagas)
│           │
│         (Outbox TX)
RateLimit     Outbox Table ──Publisher ──Kafka/Pulsar ──Consumers
│                      │
WAF                     └─DLQ/Replay
│
└─Ledger/Wallet (ACID, idempotent debit/credit)
│
└─CDC/Changefeed ──DWH/BI/ReconLugares clave: Outbox (registro atómico del equipo y «borrador» del evento), Publisher (entrega de exactamente uno), Consumers (idempotente, con clave de dedup), DLQ/Replay (repeticiones controladas).
4) Invariantes monetarios y coherencia
La verdad sobre el balance es Ledger (ACID, transacciones serializables o un arreglo estricto de la cuenta).
Los equipos monetarios: 'debit', 'credit', 'hold',' commit ',' rollback 'son idempotentes.
Los procesos combinados se construyen como sagas:- 'authorize → settle → credit' (depósito/retitulación), 'request → submit → settled/failed' (pago/retiro), 'refund/void' (compensación).
- No hay correcciones directas de balances por Ledger.
5) Idempotencia: diseño de llaves
La clave debe identificar inequívocamente la operación empresarial:- `bet_id+amount+currency`, `payment_intent+capture_id`, `payout_id`, `chain_txid`.
- Almacenar el resultado por clave (responder cache). La repetición con la misma clave → el mismo cuerpo/estado.
- Controla la inconsistencia: la misma clave con otra suma → 'IDEMPOTENCY _ MISMATCH'.
6) Colas, orden y dedoup
Exactly-once los efectos no se logran por transporte, sino por consumers idempotentes + dedup storage (LRU/Redis/DB c TTL).
Guarde el orden por clave (partition key = 'account _ id/round _ id/player _ id').
Para claves «heterogéneas», versionar el estado y los conmutadores (state machine per entity).
La DLQ es obligatoria: después de N intentos - en un tema aislado con causa humanizable.
7) Outbox/CDC: por qué los eventos «no se pierden»
Como parte de una sola transacción en el DB del servicio, registramos tanto el cambio comercial como la entrada en el outbox.
Un publisher independiente lee outbox y publica en un bus de confirmación.
Alternativamente, CDC (Change Data Capture) en el nivel de DB (Debezium/registro de replicación).
Ningún «registro de eventos» más allá de una transacción es una fuente de pérdida.
8) Back-pressure y prioridades
Token baquetas y cuotas de entrada (per tenant/brand/region).
Colas con prioridad: las rutas de dinero por encima de la promo/telemetría.
En caso de sobrecarga: modos 'no new sessions/requests', congelación de fichas secundarias, conservación del núcleo.
Auto-degradación: reducir la frecuencia de las tareas de fondo, expandir dinámicamente los workers críticos.
9) Sostenibilidad multirregional
Activo-activo para API y colas, Ledger local (o global con sharding por región/moneda).
Residencia de datos: el dinero/PII/revistas no se cruzan sin reglas explícitas.
La replicación de eventos interregional es asíncrona, con la etiqueta 'región'.
RPO/RTO: apunte RPO ≤ 5 minutos, RTO ≤ 30 minutos; revise regularmente.
10) SLO/SLI y dashboards
Puntos de referencia (ejemplo):- p95 'authorize/debit/credit' <150-300 ms (ruta interior).
- p95 end-to-end «komanda→sobytiye en el bus» <1-2 s.
- Entrega de webhooks/eventos externos p99 <5 min.
- «Transacciones perdidas/duplicadas» = 0 (verificaciones contractuales).
Métricas: latency p50/p95/p99, error-rate (4xx/5xx/business), consumer/queue lag, retry storms, settle lag, webhook lag, tamaño DLQ, frecuencia 'IDEMPOTS ENCY _ MISMATCH'.
11) Observabilidad y auditoría
Registros JSON estructurados con 'trace _ id', 'idempotency _ key', ID de negocio, códigos de error.
OpenTelemetry: tracking HTTP/gRPC/DB/bus, sagas de dormir.
Auditoría WORM: registros de cambios críticos inmutables (límites, claves, confecciones promocionales/jackpots).
Enmascarar PII/secretos, baquetas regionales, RBAC/ABAC para acceder a los logotipos.
12) Pruebas de fiabilidad
Pruebas contractuales: repetición/duplicado, fuera de orden, idempotencia, dedoup.
Carga: perfil de picos (x10), estabilidad de colas y DB.
Casos de caos: la caída de Ledger/billetera, las colas/regiones, los retrasos de los CDC, la «tormenta» de los retraídos.
Días de juego: ejercicios regulares de RD e incidentes, con medición MTTR.
13) Almacenamiento y datos
OLTP bajo dinero: DAB transaccional (RPO≈0), índices estrictos, niveles serializables por entidades críticas.
Caché (Redis): sólo para acelerar, no para «la verdad». TTL + jitter, protección contra cache stampede.
OLAP/DWH - para informes/análisis. Flujos de CDC/bus, sin carga OLTP.
Los esquemas de datos se versionan; migraciones sin downtime (expand/aprox.).
14) Orquesta de Retraídos
Backoff + jitter exponencial, deduplines/timeout en RPC.
Repetición idempotente en cada capa (cliente → servicio → consumidor).
Cupos para retiros, protegerse de las «tormentas» (circuit breaker, hedged requests cuando corresponda).
Replay desde DLQ sólo a ventanas «seguras», con límite de velocidad.
15) Seguridad de los transportes
mTLS en todas partes S2S, tokens de vida corta (OAuth2 CC), firmas de cuerpos (HMAC/EdDSA) para webhooks.
Secretos en Vault/HSM, rotación, llaves por marca/región.
Los políticos least privilege, «cuatro ojos» a las operaciones manuales.
16) Contratos de ejemplo (fragmentos)
Equipo idempotente de débito
POST /v1/wallet/debit
Headers: X-Idempotency-Key: debit_pi_001, X-Trace-Id: tr_a1b2
{
"account_id":"acc_42",  "amount":{"minor_units":5000,"currency":"EUR"},  "reason":"payout",  "reference_id":"po_001"
}
→ 200 { "status":"committed", "entry_id":"e_77" }
(repetición → la misma respuesta)Evento de outbox
json
{
"event_id":"uuid",  "event_type":"wallet. debit. committed",  "occurred_at":"2025-10-23T16:21:05Z",  "account_id":"acc_42",  "amount_minor":5000,  "currency":"EUR",  "reference_id":"po_001",  "idempotency_key":"debit_pi_001",  "schema_version":"1. 3. 0"
}17) Hojas de cheques
Plataforma/operador
- La verdad sobre el equilibrio es un Ledger; no hay soluciones.
- Todas las operaciones de escritura con 'Idempotency-Key'; se almacena la respuesta por clave.
- Outbox/CDC para todos los registros de dominio, DLQ y replay administrado.
- Colas con prioridades, back-pressure, modos de degradación.
- Partition-keys están seleccionados por claves de negocio; los consumidores son idempotentes.
- SLO-dashboards, OpenTelemetry, auditoría WORM.
- Ejercicios regulares de RD/xaoc, pruebas contractuales/de carga.
- Residencia de datos, cifrado, Vault/HSM, rotación de claves.
Proveedores/Integraciones
- Envío 'Trace-Id '/' Idempotency-Key', listo para volver a entregar.
- Webhooks firmados y deduplicados.
- Se cumplen las versiones de esquemas/contratos (semver, deprecation).
18) Banderas rojas (anti-patrones)
El balance cambia a través del webhook sin un equipo en Ledger.
Falta de idempotencia → doble cargo/crédito.
Publicación de eventos omitiendo outbox/CDC.
Monolito sin back-pressure: el pico del tráfico lo roza todo.
Mezcla de OLTP y reportes: BI golpea el BD de combate.
Ausencia de DLQ/réplica; «silenciosa» ingestión de errores.
No hay aislamiento regional de PII/dinero; claves compartidas en varias marcas.
Correcciones manuales de balances/estados en la DAB.
19) Resultado
Fail-safe procesa millones de transacciones al día es sobre invariantes y disciplina: una sola fuente de verdad, comandos idempotentes, sagas y outbox/CDC, orden y dedoup en colas, observabilidad y degradaciones controladas. Agregue mandatos de acceso, prácticas de DR y ejercicios regulares - y obtenga un sistema donde el dinero se mueve rápidamente y sólo una vez, los eventos no se pierden, y el aumento del tráfico y las interrupciones se convierten en riesgos manejables en lugar de sorpresas.
