Eventos asíncronos
Cómo funcionan los flujos asíncronos basados en eventos: publicación, consumo y procesamiento entre microservicios a través del Event Bus.
Qué es un flujo asíncrono basado en eventos
En un flujo asíncrono, un servicio publica un evento indicando que algo ocurrió, y otros servicios reaccionan a ese evento sin que el publicador necesite esperar una respuesta. No hay una conexión directa entre quien produce el evento y quien lo consume.
Este modelo es fundamental en arquitecturas distribuidas porque permite desacoplamiento temporal: los servicios no necesitan estar disponibles al mismo tiempo para comunicarse.
Diferencia con la comunicación sincrónica
| Aspecto | Sincrónico | Asíncrono (eventos) |
|---|---|---|
| Acoplamiento | El emisor conoce al receptor | El emisor no sabe quién consume |
| Disponibilidad | Ambos deben estar activos | El consumidor puede procesar después |
| Respuesta | Inmediata | No hay respuesta directa |
| Escalabilidad | Limitada por el receptor más lento | Cada consumidor escala independientemente |
| Complejidad | Menor | Mayor (orden, duplicados, consistencia) |
Anatomía de un evento
Un evento bien definido contiene:
- Tipo: nombre que identifica qué ocurrió (
OrderPlaced,PaymentCompleted) - Payload: datos relevantes del hecho (ID de la orden, monto, timestamp)
- Metadata: información de trazabilidad (correlationId, timestamp, source)
- Versión: para manejar evolución del esquema
{
"type": "OrderPlaced",
"version": "1.0",
"timestamp": "2024-01-15T10:30:00Z",
"correlationId": "abc-123-def",
"source": "ms-orders",
"payload": {
"orderId": "order-456",
"customerId": "cust-789",
"totalAmount": 150.00,
"items": [
{ "productId": "prod-001", "quantity": 2 }
]
}
}
El flujo completo de un evento
sequenceDiagram
participant MS1 as Microservicio Origen
participant EB as Event Bus
participant MS2 as Consumidor A
participant MS3 as Consumidor B
participant MS4 as Consumidor C
MS1->>EB: Publicar evento (OrderPlaced)
Note over MS1: El publicador continúa su trabajo
EB->>MS2: Entregar evento
EB->>MS3: Entregar evento
EB->>MS4: Entregar evento
MS2->>MS2: Actualizar inventario
MS3->>MS3: Enviar notificación
MS4->>MS4: Registrar analytics
Paso 1: Publicación
El microservicio origen completa su operación principal (por ejemplo, crear una orden) y publica un evento al Event Bus. Una vez publicado, el servicio no espera a que nadie lo procese.
Paso 2: Distribución
El Event Bus recibe el evento y lo distribuye a todos los consumidores suscritos. Dependiendo de la tecnología (Kafka, RabbitMQ, SNS/SQS), la distribución puede ser:
- Fan-out: todos los suscriptores reciben una copia
- Competencia: solo un consumidor del grupo procesa cada mensaje
- Combinación: fan-out entre grupos, competencia dentro de cada grupo
Paso 3: Consumo
Cada consumidor recibe el evento y ejecuta su lógica de forma independiente. Un consumidor lento no afecta a los demás.
Paso 4: Confirmación
El consumidor confirma (acknowledge) que procesó el evento correctamente. Si falla, el Event Bus puede reintentar la entrega.
Patrones de publicación
Publicar después de persistir
El servicio primero guarda en su base de datos y luego publica el evento. Es simple pero tiene un riesgo: si la publicación falla después de persistir, el evento se pierde.
Outbox Pattern
El servicio guarda el evento en una tabla outbox dentro de la misma transacción que la operación de negocio. Un proceso separado lee la tabla outbox y publica los eventos al bus. Esto garantiza consistencia entre la operación y la publicación.
Event Sourcing
En lugar de guardar el estado actual, se guardan todos los eventos que produjeron ese estado. La publicación es inherente al modelo.
Desafíos de los flujos asíncronos
Orden de eventos
Los eventos pueden llegar en orden diferente al que fueron publicados. Los consumidores deben ser capaces de manejar esto, ya sea reordenando o siendo tolerantes al desorden.
Eventos duplicados
El Event Bus puede entregar el mismo evento más de una vez (at-least-once delivery). Los consumidores deben ser idempotentes: procesar el mismo evento dos veces debe producir el mismo resultado que procesarlo una vez.
Consistencia eventual
Los datos entre servicios no están sincronizados instantáneamente. Después de publicar un evento, puede pasar un tiempo antes de que todos los consumidores reflejen el cambio. El sistema debe diseñarse para tolerar esta ventana de inconsistencia.
Observabilidad
Rastrear un flujo asíncrono es más difícil que uno sincrónico. El correlationId es esencial para poder seguir la cadena de eventos a través de múltiples servicios.
Cuándo usar eventos asíncronos
Son adecuados cuando:
- Múltiples servicios necesitan reaccionar al mismo hecho
- No se necesita una respuesta inmediata
- Se quiere desacoplar servicios para escalar independientemente
- El proceso puede tolerar consistencia eventual
No son adecuados cuando:
- Se necesita una respuesta inmediata para el usuario
- La operación requiere consistencia fuerte entre servicios
- La complejidad añadida no se justifica por el volumen o los requisitos
Resumen
Los flujos asíncronos basados en eventos permiten que los servicios se comuniquen sin acoplamiento directo. El publicador no conoce a los consumidores, y cada consumidor procesa a su ritmo. Esto aporta escalabilidad y resiliencia, pero introduce desafíos de orden, duplicados y consistencia que deben abordarse con patrones como idempotencia, outbox y trazabilidad distribuida.