Arquitecturas Event-Driven con Lambda y EventBridge
Cómo diseñar sistemas débilmente acoplados usando funciones serverless disparadas por eventos de colas de mensajes, bases de datos y webhooks.
Visión general
La arquitectura orientada a eventos elimina las llamadas HTTP directas entre servicios: en lugar de llamarse unos a otros, los servicios hablan mediante eventos. Cuando un usuario sube una imagen, sale un evento ImageUploaded. Un generador de miniaturas lo escucha y crea la versión redimensionada; un extractor de metadatos lo escucha también y actualiza el índice de búsqueda. Ningún servicio sabe que el otro existe — solo conoce el evento.
Las funciones serverless encajan bien en este modelo: cuestan cero en reposo y se levantan solas cuando llega una ráfaga de eventos. AWS Lambda, SQS, EventBridge y SNS forman la columna vertebral de la mayoría de plataformas serverless event-driven.
Cuándo usarlo
Usa esta receta cuando:
- Procesas cargas asíncronas que no necesitan respuesta inmediata (procesamiento de imágenes, generación de informes, envío de emails)
- Quieres desacoplar servicios para desplegarlos, escalarlos y fallarlos de forma independiente
- Un mismo evento debe llegar a varios consumidores — cada uno reaccionando de forma distinta al mismo hecho
- El sistema debe absorber picos de tráfico sin aprovisionar capacidad por adelantado
- Hay que reaccionar a cambios en los datos (CDC de base de datos) o en sistemas externos (webhooks, subidas de archivos)
No uses event-driven cuando quien llama necesita el resultado de forma síncrona, cuando solo hay un consumidor para siempre, o cuando el orden estricto de extremo a extremo es un requisito duro — una cola simple o una llamada directa serán más sencillas.
Solución
Lambda disparada por SQS (Python)
import json
import boto3
def lambda_handler(event, context):
for record in event['Records']:
body = json.loads(record['body'])
order_id = body['orderId']
# Procesa el pedido de forma asíncrona
process_order(order_id)
# El mensaje SQS se elimina automáticamente al completar con éxito
return {'statusCode': 200}
def process_order(order_id):
# Lógica de negocio: validar, cobrar, notificar
print(f"Procesando pedido {order_id}")
Regla de EventBridge (Infraestructura como Código)
# SAM / CloudFormation
OrderPlacedRule:
Type: AWS::Events::Rule
Properties:
EventBusName: default
EventPattern:
source:
- order-service
detail-type:
- OrderPlaced
Targets:
- Arn: !GetAtt PaymentFunction.Arn
Id: payment-target
- Arn: !GetAtt NotificationFunction.Arn
Id: notification-target
Publicando Eventos (Node.js)
const { EventBridgeClient, PutEventsCommand } = require('@aws-sdk/client-eventbridge');
const eb = new EventBridgeClient({ region: 'us-east-1' });
async function publishOrderPlaced(order) {
await eb.send(new PutEventsCommand({
Entries: [{
Source: 'order-service',
DetailType: 'OrderPlaced',
Detail: JSON.stringify({
orderId: order.id,
amount: order.total,
customerEmail: order.email,
}),
}],
}));
}
Explicación
- Eventos: registros inmutables de algo que ocurrió (
OrderPlaced,ImageUploaded,PaymentReceived). Los eventos llevan estado pero no dictan qué deben hacer los consumidores. - Productores de eventos: servicios que emiten eventos cuando ocurre algo relevante. Un productor no sabe ni le importa cuántos consumidores escuchan.
- Consumidores de eventos: funciones o servicios suscritos a tipos de evento concretos. Distintos consumidores pueden reaccionar al mismo evento a su manera.
- Buses de eventos (EventBridge): el enrutador central de una arquitectura orientada a eventos. Cada evento se compara con tus reglas y se empuja a todos los targets que coincidan — productores y consumidores quedan desacoplados.
La regla de EventBridge de arriba es el punto de fan-out: un evento OrderPlaced se enruta a la vez a la función de pagos y a la de notificaciones, sin acoplamiento de código entre ellas:
Variantes
| Patrón | Acoplamiento | Durabilidad | Ideal para |
|---|---|---|---|
| Invocación directa | Fuerte | Ninguna | Flujos simples y síncronos |
| Colas SQS | Débil | Alta | Procesamiento async fiable, reintentos |
| EventBridge | Débil | Alta | Enrutado multi-consumidor, filtrado |
| Topics SNS | Débil | Media | Broadcast, notificaciones fan-out |
| Streams Kinesis | Débil | Alta | Analítica en tiempo real, procesamiento ordenado |
Para el ajuste fino de SQS — ventanas de batch, respuestas de batch parcial y cableado de dead-letter queue — consulta Lambda Event-Driven con Triggers SQS.
Fuera de AWS, la misma topología se traduce a los equivalentes de cada proveedor:
| Rol | AWS | Azure | GCP |
|---|---|---|---|
| Función | Lambda | Azure Functions | Cloud Functions |
| Bus de eventos | EventBridge | Event Grid | Eventarc |
| Cola | SQS | Storage Queues / Service Bus | Pub/Sub |
| Topic fan-out | SNS | Topics de Event Grid | Topics de Pub/Sub |
El modelo de acoplamiento — eventos, productores, consumidores, dead letters — es idéntico; solo cambian los nombres de servicio y las llamadas del SDK.
Lo que funciona
- Diseña eventos en torno a hechos de negocio:
OrderPlacedes mejor queProcessOrder— describe qué ocurrió, no qué hacer, así que los consumidores siguen libres de reaccionar de forma distinta. - Haz los eventos inmutables y autocontenidos: incluye suficiente contexto (ID de pedido, email del cliente, importe) para que el consumidor no tenga que llamar de vuelta al productor.
- Planifica para duplicados: la mayoría de colas entregan at-least-once, así que el mismo evento puede llegar dos veces. Los consumidores deben ser idempotentes o desduplicar usando los IDs de evento.
- Configura dead letter queues: tras el número de reintentos configurado, los mensajes fallidos van a una DLQ para inspección en lugar de reintentar para siempre.
- Monitoriza latencia y edad de eventos: los mensajes viejos señalan un cuello de botella de procesamiento. Alarma sobre
ApproximateAgeOfOldestMessageen SQS. - Funciones de propósito único: cada función hace una cosa bien — la orquestación vive en las reglas del bus o en Step Functions, no dentro del handler.
Errores comunes
- Tratar los eventos como comandos:
ProcessPaymentespera una acción;PaymentRequesteddescribe un hecho. Los comandos crean acoplamiento fuerte — los eventos promueven el débil. - Omitir el versionado del esquema: cuando cambia el esquema de un evento, los consumidores no actualizados fallan. Versiona los eventos (
OrderPlaced-v2) o usa un schema registry. - No manejar fallos parciales de batch: con batch sizes de SQS por encima de 1, un mensaje malo puede tumbar todo el batch a menos que devuelvas fallos por ítem (
batchItemFailures). - Ignorar el orden de los mensajes: las colas estándar de SQS no garantizan orden — usa FIFO o números de secuencia solo cuando el orden sea un requisito real.
- Guardar estado compartido en la función: las instancias son efímeras; el estado va en DynamoDB, S3 o en el propio evento.
Solución de problemas
- Los mensajes reintentan sin éxito una y otra vez: hay un poison message atascado en el bucle de reintentos — verifica que la DLQ esté conectada (
redrivePolicyen la cola) e inspecciona el payload fallido buscando un desajuste de esquema. - Un registro malo mata todo el batch: devuelve
batchItemFailurescon losmessageIdfallidos desde el handler para que solo esos reintenten — si no, Lambda reproduce todo el lote. - El evento llega pero ningún consumidor salta: el patrón de la regla de EventBridge no hace match — pruébalo en la consola contra los valores exactos de
source/detail-type;DetailTypedistingue mayúsculas. - Los consumidores ven eventos fuera de orden: ni SQS estándar ni EventBridge preservan el orden — incluye un número de secuencia o timestamp en el payload y reordena en el consumidor si hace falta.
- Efectos duplicados (doble cobro, doble email): entrega at-least-once — haz el consumidor idempotente guardando los
event.idprocesados antes de ejecutar el efecto.
Ver también
- Lambda Event-Driven con Triggers SQS — ventanas de batch de SQS, respuestas parciales, cableado de DLQ
- Diseña Sistemas Event-Driven — buses de eventos, brokers y patrones de diseño pub/sub
- Patrón de Event Sourcing — almacenar el estado como un log de eventos inmutable
- Scheduled Jobs — cuándo un trigger de cron, no un evento, es la respuesta correcta
- Documentación de Amazon EventBridge — reglas, patrones de eventos y cuotas
- Documentación del trigger SQS de Lambda — batching, fallos parciales y escalado
- Repositorio companion — handler ejecutable, plantilla SAM y script de publicación
Preguntas frecuentes
¿En qué se diferencia event-driven de request-response?
Request-response (HTTP REST) es síncrono: quien llama espera un resultado. Event-driven es asíncrono: el productor dispara un evento y sigue mientras los consumidores procesan cuando pueden.
¿Puedo usar arquitectura event-driven con proveedores que no sean AWS?
Sí. Azure Functions con Event Grid, Google Cloud Functions con Pub/Sub y Apache Kafka en cualquier nube soportan patrones event-driven — el modelo de acoplamiento es el mismo, solo cambian los nombres de los servicios.
¿Cómo trazo una petición a través de varias funciones event-driven?
Genera un correlation ID en el punto de entrada y propágalo por los atributos de cada evento — X-Ray u OpenTelemetry reconstruyen la cadena completa.
¿Cuál es el tamaño máximo de un evento?
Los mensajes SQS están limitados a 256 KB, y los eventos de EventBridge también a 256 KB. Para payloads mayores, guarda los datos en S3 y envía solo la referencia — el patrón claim-check.
¿Importa el orden de los eventos en funciones serverless?
Solo a veces. La mayor parte del trabajo event-driven es insensible al orden por diseño; cuando el orden importa (inventario, contabilidad), usa SQS FIFO con un message group ID, o lleva un campo de secuencia y deja que los consumidores apliquen el último-gana.
¿Qué pasa si un consumidor está caído cuando llega el evento?
No se pierde nada: EventBridge reintenta la entrega (hasta 185 veces en 24 horas por defecto) y SQS retiene los mensajes hasta que expira el visibility timeout. Configura la DLQ de todos modos para que los reintentos agotados aterricen en algún sitio inspeccionable.
Recursos Relacionados
Construir APIs Serverless con API Gateway
Cómo diseñar, desplegar y gestionar APIs HTTP serverless usando AWS API Gateway, Lambda y patrones de function-as-a-service.
RecipeWebhooks: Notificaciones HTTP
Cómo crear y consumir endpoints de webhook para integraciones event-driven en tiempo real.
RecipeEjecutar Jobs Programados con Funciones Serverless
Cómo reemplazar cron jobs con funciones serverless programadas para backups, reportes, limpieza y tareas de mantenimiento periódico.
RecipeDiseñar Sistemas Event-Driven con Event Buses y Brokers
Cómo diseñar servicios débilmente acoplados con eventos, event buses y message brokers: patrones pub/sub y event sourcing para comunicación asíncrona.
RecipeConstruir Lambda Event-Driven con Triggers SQS y Batch
Procesar mensajes SQS con Lambda usando batch windows, partial batch responses, manejo de errores y dead-letter queues para pipelines event-driven resilientes.
PatternPatrón Event Sourcing
Almacena el estado de una aplicación como secuencia de eventos en lugar de guardar solo el estado actual. Patrón arquitectónico para sistemas auditables.