Saltar al contenido

lección 2

EventBridge + SQS: montar eventos serverless con LocalStack

Levanta EventBridge y SQS con LocalStack. Configura buses, colas, reglas y targets desde cero.

55 min

### Objetivo: tu laboratorio de eventos en 10 minutos

En la Skill 14 (Cloud AWS) ya instalaste LocalStack y la CLI de AWS para emular servicios en tu máquina. Ahora vamos a usarlo para montar un sistema de eventos COMPLETO: un bus de EventBridge que recibe eventos y los enruta a colas SQS según reglas que tú defines. Sin pagar un céntimo a Amazon, sin cuenta AWS, todo en tu portátil.

La analogía perfecta: EventBridge es la CENTRALITA TELEFÓNICA de un hotel. Cuando alguien llama (evento), la centralita mira las reglas (¿es una llamada para recepción? ¿para limpieza? ¿para el restaurante?) y la redirige al teléfono correcto (target). SQS es el BUZÓN donde se acumula el mensaje hasta que alguien lo recoge. La llamada no se pierde si no hay nadie al otro lado — queda en el buzón.

### Verificar que LocalStack está funcionando

Si ya tienes LocalStack del Skill anterior, simplemente verifica que está corriendo. Si no, levántalo con Docker:

1# Verificar que LocalStack está corriendo
2# Windows (PowerShell) y Mac (Terminal):
3docker ps | grep localstack
4
5# Si no está corriendo, levántalo:
6docker run -d --name localstack -p 4566:4566 -p 4510-4559:4510-4559 -e SERVICES=sqs,events -e DEFAULT_REGION=eu-west-1 localstack/localstack:3.5
7
8# Verificar que responde:
9aws --endpoint-url=http://localhost:4566 sts get-caller-identity

LocalStack emula SQS y EventBridge en localhost:4566

### SQS: tu primera cola de mensajes

SQS (Simple Queue Service) es una cola de mensajes. Piensa en ella como un buzón de correos: alguien deposita un mensaje y otro lo recoge cuando está listo. El mensaje permanece en el buzón hasta que es leído y confirmado (deleted). Es la forma más simple de desacoplar dos servicios: el productor mete mensajes en la cola y se olvida. El consumidor los saca cuando puede.

1# Crear una cola SQS en LocalStack
2# Windows (PowerShell) y Mac (Terminal):
3aws --endpoint-url=http://localhost:4566 sqs create-queue \
4 --queue-name pedidos-nuevos --region eu-west-1
5
6# Crear una segunda cola para notificaciones:
7aws --endpoint-url=http://localhost:4566 sqs create-queue \
8 --queue-name notificaciones-email --region eu-west-1
9
10# Listar colas existentes:
11aws --endpoint-url=http://localhost:4566 sqs list-queues --region eu-west-1

Crear y verificar colas SQS en LocalStack

### EventBridge: crear un bus de eventos

EventBridge tiene un bus por defecto llamado "default", pero en producción siempre creas buses personalizados para separar dominios. Piénsalo como tener centralitas distintas para cada departamento del hotel. El bus de "ecommerce" no necesita enterarse de los eventos del bus de "rrhh".

1# Crear un bus de eventos personalizado
2# Windows (PowerShell) y Mac (Terminal):
3aws --endpoint-url=http://localhost:4566 events create-event-bus \
4 --name ecommerce-bus --region eu-west-1
5
6# Listar buses disponibles:
7aws --endpoint-url=http://localhost:4566 events list-event-buses --region eu-west-1

Un bus personalizado separa los eventos de tu dominio

### Reglas: el cerebro del routing

Las reglas de EventBridge son el mecanismo de ROUTING inteligente. Cada regla tiene un event pattern (filtro) que decide qué eventos le interesan y un target (destino) donde enviarlos. Es como un filtro de email: "si el remitente es pedidos y el asunto contiene PedidoCreado, mover a la carpeta Nuevos Pedidos".

1# Crear una regla que capture eventos de tipo "PedidoCreado"
2QUEUE_ARN="arn:aws:sqs:eu-west-1:000000000000:pedidos-nuevos"
3
4aws --endpoint-url=http://localhost:4566 events put-rule \
5 --name regla-pedidos-creados \
6 --event-bus-name ecommerce-bus \
7 --event-pattern '{"detail-type": ["PedidoCreado"]}' \
8 --region eu-west-1
9
10# Asignar la cola SQS como target:
11aws --endpoint-url=http://localhost:4566 events put-targets \
12 --rule regla-pedidos-creados \
13 --event-bus-name ecommerce-bus \
14 --targets "Id=target-sqs-pedidos,Arn=$QUEUE_ARN" \
15 --region eu-west-1

Reglas filtran por patrón y envían a targets diferentes

EventBridge actúa como centralita: recibe un evento y lo enruta a los targets correctos

### Enviar y recibir tu primer evento con Python

Ahora que tenemos la infraestructura lista, vamos a usarla con boto3. Produciremos un evento desde Python y veremos cómo aparece en la cola SQS del otro lado. Es el momento "aha" donde todo cobra sentido.

1import boto3
2import json
3
4# Crear cliente apuntando a LocalStack
5eb = boto3.client(
6 "events",
7 endpoint_url="http://localhost:4566",
8 region_name="eu-west-1",
9 aws_access_key_id="test",
10 aws_secret_access_key="test",
11)
12
13# Publicar un evento en el bus
14response = eb.put_events(
15 Entries=[
16 {
17 "Source": "servicio-pedidos",
18 "DetailType": "PedidoCreado",
19 "Detail": json.dumps({
20 "pedido_id": "ORD-2024",
21 "cliente_id": "CLI-55",
22 "total": 79.99
23 }),
24 "EventBusName": "ecommerce-bus",
25 }
26 ]
27)
28print(f"Eventos publicados: {response['FailedEntryCount']} fallos")

Publicar un evento con boto3 — el productor solo dice "esto pasó"

1import boto3
2import json
3
4# Leer mensajes de la cola SQS
5sqs = boto3.client(
6 "sqs",
7 endpoint_url="http://localhost:4566",
8 region_name="eu-west-1",
9 aws_access_key_id="test",
10 aws_secret_access_key="test",
11)
12
13queue_url = "http://sqs.eu-west-1.localhost.localstack.cloud:4566/000000000000/pedidos-nuevos"
14
15response = sqs.receive_message(
16 QueueUrl=queue_url,
17 MaxNumberOfMessages=10,
18 WaitTimeSeconds=20,
19)
20
21for msg in response.get("Messages", []):
22 body = json.loads(msg["Body"])
23 print(f"Evento recibido: {json.dumps(body, indent=2)}")
24 # Confirmar procesamiento (borrar de la cola)
25 sqs.delete_message(QueueUrl=queue_url, ReceiptHandle=msg["ReceiptHandle"])
26 print("Mensaje confirmado y eliminado de la cola")

Consumir de SQS: leer, procesar y confirmar (delete) el mensaje

### Anatomía de una cola SQS

SQS tiene dos sabores: Standard (alta throughput, orden no garantizado, puede duplicar) y FIFO (orden garantizado, exactly-once en la cola, 300 transacciones/s por acción — hasta 3.000 msg/s con lotes de 10, y hasta 9.000 TPS por acción en high throughput mode desde 2023). Para la mayoría de casos event-driven, Standard es suficiente si tu consumidor es idempotente. FIFO es para cuando el ORDEN importa — procesar pagos de un mismo cliente en secuencia, por ejemplo.

  • Visibility timeout: tiempo que un mensaje es "invisible" tras ser leído (default 30s). Si el consumidor no lo borra en ese tiempo, vuelve a aparecer.
  • Retention period: cuánto tiempo se guarda un mensaje no leído (default 4 días, máx 14).
  • Dead Letter Queue (DLQ): cola donde van los mensajes que fallan N veces. La "morgue" de mensajes.
  • Long polling: el consumidor espera hasta X segundos a que llegue un mensaje (vs polling constante vacío).

Consejo de senior: configura SIEMPRE una Dead Letter Queue. Si un mensaje falla 3 veces, algo está mal y repetirlo infinitamente no va a arreglarlo. La DLQ te da un sitio donde investigar mensajes problemáticos sin bloquear el flujo principal.

Lo que le diría a mi yo de hace 5 años: usa Long Polling (WaitTimeSeconds=20) SIEMPRE. Sin long polling, tu consumidor hace miles de peticiones vacías por minuto = dinero tirado y CPU desperdiciada.

Cuidado con el visibility timeout. Si tu procesamiento tarda más que el timeout, el mensaje "reaparece" en la cola y OTRO consumidor lo procesa también. Resultado: duplicados. Ajusta el timeout al tiempo real de procesamiento + margen.

### Resumen de lo montado

En esta lección has montado un laboratorio completo de eventos: LocalStack corriendo, un bus personalizado de EventBridge, dos colas SQS, reglas de routing que filtran por tipo de evento, y un productor/consumidor en Python. En la siguiente lección construiremos un flujo event-driven completo de principio a fin.

## ejercicios

[01]

Crear una cola con Dead Letter Queue

Crea una cola SQS principal llamada "pagos" y una DLQ llamada "pagos-dlq". Configura la cola principal para que envíe mensajes a la DLQ tras 3 intentos fallidos usando RedrivePolicy. Qué deberías ver: create-queue devuelve un JSON con QueueUrl; get-queue-attributes debe mostrar RedrivePolicy con tu deadLetterTargetArn y maxReceiveCount: 3.

Cargando editor...
[02]

Regla con filtro avanzado en EventBridge

Crea una regla de EventBridge que solo capture eventos de tipo "PedidoCreado" donde el total sea mayor a 100 euros (filtro numérico). Asígnala a una cola SQS "pedidos-vip". Qué deberías ver: put-rule devuelve un RuleArn; put-targets devuelve FailedEntryCount: 0. Para probarlo, publica un evento con total 250 y otro con total 50 — solo el de 250 debe llegar a pedidos-vip.

Cargando editor...
[03]

Publicar un evento desde Python con boto3

Escribe un script Python que publique un evento "UsuarioRegistrado" en el bus "ecommerce-bus" de LocalStack. Incluye datos del usuario (id, email, plan). Qué deberías ver: FailedEntryCount: 0 confirma que el evento se publicó. Si ves FailedEntryCount: 1, revisa que el bus exista y que Detail sea un string JSON, no un dict.

Cargando editor...
[04]

Consumidor SQS con long polling y confirmación

Escribe un consumidor que lea de la cola "pedidos-nuevos" usando long polling (20s), procese cada mensaje imprimiendo su contenido, y lo elimine de la cola para confirmar el procesamiento. Qué deberías ver: si la cola tiene mensajes, "Recibidos: N mensajes" y el JSON de cada evento; si está vacía, "Cola vacía (o timeout de long polling)" tras 20 segundos de espera — eso es long polling funcionando, no un error.

Cargando editor...

Regístrate para guardar tu progreso.

## comentarios

Reporta erratas, ayuda a otros o comparte tu opinión. Sé constructivo.

Inicia sesión para comentar y responder.

cargando comentarios...