AWS EventBridge: 서버리스 이벤트 버스 및 콘텐츠 기반 라우팅
Amazon EventBridge는 AWS의 서버리스 이벤트 버스입니다. 콘텐츠 Lambda, SQS, Step Functions, API 대상 및 기타 수십 개의 대상을 대상으로 합니다. SNS와 달리 모든 구독자에게 공개되지 않고 적용됩니다. 지능형 라우팅 규칙 페이로드 필드를 기반으로 합니다. 통합 스키마 레지스트리를 사용하면 스키마 오류가 감지됩니다. 런타임이 아닌 게시 시간에.
EventBridge 아키텍처: 버스, 규칙, 대상
EventBridge는 세 가지 기본 개념으로 구성됩니다.
- 이벤트 버스: 이벤트를 수신하는 채널입니다. 각 AWS 계정에는 기본 이벤트 버스 (EC2, S3, RDS와 같은 AWS 서비스로부터 이벤트 수신), 여러 사용자 정의 버스(맞춤형 이벤트 버스) 애플리케이션 이벤트의 경우 e 파트너 이벤트 버스 SaaS 통합용(Zendesk, Datadog, Salesforce).
- 이벤트 규칙: 규칙 이벤트 패턴 (JSON 필터)를 결정합니다. 어떤 이벤트를 어떤 대상으로 라우팅할지. 단일 규칙에는 최대 5개의 대상이 있을 수 있습니다.
- 목표: 이벤트의 대상입니다. Lambda, SQS, SNS, Step Functions를 지원합니다. API Gateway, Kinesis, 다른 계정의 EventBridge 버스 및 20개 이상의 기타 대상.
EventBridge 이벤트의 구조
{
"version": "0",
"id": "12345678-1234-1234-1234-123456789012",
"source": "com.mioapp.ordini",
"account": "123456789012",
"time": "2026-03-20T10:30:00Z",
"region": "eu-west-1",
"detail-type": "OrdineEffettuato",
"detail": {
"ordineId": "ord-abc123",
"clienteId": "cli-xyz789",
"totale": 149.99,
"stato": "IN_ATTESA_PAGAMENTO",
"categoria": "ELETTRONICA"
}
}
분야 detail 애플리케이션 페이로드를 포함합니다. source e detail-type 이벤트 유형을 식별합니다.
EventBridge에 이벤트 게시
// EventBridgePublisher.java - Pubblica eventi custom su EventBridge
import software.amazon.awssdk.services.eventbridge.EventBridgeClient;
import software.amazon.awssdk.services.eventbridge.model.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.*;
public class EventBridgePublisher {
private final EventBridgeClient eventBridgeClient;
private final ObjectMapper objectMapper;
private static final String EVENT_BUS_NAME = "mioapp-production";
public EventBridgePublisher() {
this.eventBridgeClient = EventBridgeClient.builder()
.region(Region.EU_WEST_1)
.build();
this.objectMapper = new ObjectMapper();
}
public void publishOrdineEffettuato(OrdineEffettuatoEvent event) throws Exception {
String detailJson = objectMapper.writeValueAsString(event);
PutEventsRequestEntry entry = PutEventsRequestEntry.builder()
.source("com.mioapp.ordini")
.detailType("OrdineEffettuato")
.detail(detailJson)
.eventBusName(EVENT_BUS_NAME)
// TraceHeader per X-Ray distributed tracing (opzionale)
.traceHeader("Root=1-63441c4a-abcdef")
.build();
PutEventsResponse response = eventBridgeClient.putEvents(
PutEventsRequest.builder()
.entries(entry)
.build()
);
if (response.failedEntryCount() > 0) {
response.entries().forEach(e -> {
if (e.errorCode() != null) {
throw new EventPublishException(
"Errore pubblicazione evento: " + e.errorCode() + " - " + e.errorMessage()
);
}
});
}
}
// Batch publish (max 10 eventi per chiamata, 256 KB totale)
public void publishBatch(List<DomainEvent> events) throws Exception {
List<PutEventsRequestEntry> entries = new ArrayList<>();
for (DomainEvent event : events) {
entries.add(PutEventsRequestEntry.builder()
.source("com.mioapp." + event.getAggregateType())
.detailType(event.getClass().getSimpleName())
.detail(objectMapper.writeValueAsString(event))
.eventBusName(EVENT_BUS_NAME)
.build());
}
PutEventsResponse response = eventBridgeClient.putEvents(
PutEventsRequest.builder()
.entries(entries)
.build()
);
System.out.printf("Pubblicati %d/%d eventi. Falliti: %d%n",
entries.size() - response.failedEntryCount(),
entries.size(),
response.failedEntryCount());
}
}
이벤트 패턴: 콘텐츠 기반 라우팅
EventBridge의 핵심은 콘텐츠 기반 라우팅: 규칙 필터 이벤트 유형뿐만 아니라 JSON 페이로드의 내용을 기반으로 하는 이벤트입니다. 패턴은 접두사, 접미사, 특정 값, 숫자 범위 및 음수 조건에 대한 일치를 지원합니다.
# Esempi di Event Pattern per il routing
# Pattern 1: Tutti gli ordini di importo alto (sopra 500 EUR)
{
"source": ["com.mioapp.ordini"],
"detail-type": ["OrdineEffettuato"],
"detail": {
"totale": [{ "numeric": [">", 500] }]
}
}
# Pattern 2: Ordini con prodotti della categoria ELETTRONICA o GAMING
{
"source": ["com.mioapp.ordini"],
"detail-type": ["OrdineEffettuato"],
"detail": {
"categoria": ["ELETTRONICA", "GAMING"]
}
}
# Pattern 3: Ordini di clienti premium con pagamento completato
{
"source": ["com.mioapp.ordini"],
"detail-type": ["OrdineEffettuato", "PagamentoConfermato"],
"detail": {
"tipoCliente": ["PREMIUM", "VIP"],
"stato": [{ "prefix": "PAGA" }]
}
}
# Pattern 4: Qualsiasi evento di errore da tutti i servizi dell'app
{
"source": [{ "prefix": "com.mioapp." }],
"detail-type": [{ "suffix": "Failed" }]
}
# Pattern 5: Esclusione (not): tutti gli ordini ECCETTO i test
{
"source": ["com.mioapp.ordini"],
"detail-type": ["OrdineEffettuato"],
"detail": {
"ambiente": [{ "anything-but": ["test", "staging"] }]
}
}
CloudFormation/Terraform을 사용하여 규칙 생성
# Terraform: event bus, rule e target Lambda
# Custom Event Bus
resource "aws_cloudwatch_event_bus" "mioapp" {
name = "mioapp-production"
}
# Rule: ordini ad alto valore verso Lambda di VIP handling
resource "aws_cloudwatch_event_rule" "ordini_vip" {
name = "ordini-vip-handler"
event_bus_name = aws_cloudwatch_event_bus.mioapp.name
event_pattern = jsonencode({
source = ["com.mioapp.ordini"]
detail-type = ["OrdineEffettuato"]
detail = {
totale = [{ numeric = [">", 500] }]
tipoCliente = ["PREMIUM", "VIP"]
}
})
description = "Instrada ordini VIP alto valore alla Lambda dedicata"
}
# Target: Lambda VIP handler
resource "aws_cloudwatch_event_target" "ordini_vip_lambda" {
rule = aws_cloudwatch_event_rule.ordini_vip.name
event_bus_name = aws_cloudwatch_event_bus.mioapp.name
arn = aws_lambda_function.vip_handler.arn
# Retry policy per il target
retry_policy {
maximum_event_age_in_seconds = 3600 # 1 ora
maximum_retry_attempts = 3
}
# Dead letter queue per gli eventi che non vengono consegnati
dead_letter_config {
arn = aws_sqs_queue.eventbridge_dlq.arn
}
}
# Rule: tutti gli errori verso SQS per analisi
resource "aws_cloudwatch_event_rule" "tutti_errori" {
name = "tutti-errori-sqs"
event_bus_name = aws_cloudwatch_event_bus.mioapp.name
event_pattern = jsonencode({
source = [{ prefix = "com.mioapp." }]
detail-type = [{ suffix = "Failed" }]
})
}
resource "aws_cloudwatch_event_target" "errori_sqs" {
rule = aws_cloudwatch_event_rule.tutti_errori.name
event_bus_name = aws_cloudwatch_event_bus.mioapp.name
arn = aws_sqs_queue.errori_queue.arn
}
스키마 레지스트리 및 스키마 검색
EventBridge에는 다음이 포함됩니다. 스키마 레지스트리 내장: 자동으로 검색 가능 버스에서 일어나는 사건의 패턴(검색 스키마) 정의를 유지하고 검증 및 코드 생성을 위한 스키마.
가장 큰 장점은 코드 생성: 발견된 방식에서 시작하여, EventBridge는 이벤트 페이로드에 해당하는 Java, TypeScript 또는 Python 클래스를 자동으로 생성합니다.
# Abilitare schema discovery su un event bus (AWS CLI)
aws schemas create-discoverer \
--source-arn arn:aws:events:eu-west-1:123456789012:event-bus/mioapp-production \
--description "Auto-discovery per mioapp-production"
# Elencare gli schemi scoperti
aws schemas list-schemas \
--registry-name discovered-schemas
# Scaricare il codice generato per Java
aws schemas get-code-binding-source \
--registry-name discovered-schemas \
--schema-name "com.mioapp.ordini@OrdineEffettuato" \
--language "java8" \
--schema-version "1" \
--output text > OrdineEffettuatoEvent.java
이벤트 보관 및 재생
EventBridge의 가장 강력한 기능 중 하나는이벤트 아카이브: 구성 가능한 기간 동안 버스를 통해 이동하는 모든 이벤트를 자동으로 보관합니다. 허용하는 다시 하다 과거 이벤트(프로젝션 재구축에 유용함, 생산 문제 디버깅 또는 새로운 소비자 테스트).
# Creare un archivio per il bus degli ordini
aws events create-archive \
--archive-name mioapp-ordini-archive \
--event-source-arn arn:aws:events:eu-west-1:123456789012:event-bus/mioapp-production \
--retention-days 90 \
--event-pattern '{
"source": ["com.mioapp.ordini"],
"detail-type": ["OrdineEffettuato", "PagamentoConfermato"]
}'
# Replay degli eventi archiviati (utile per rebuild di read model)
aws events start-replay \
--replay-name rebuild-read-model-20260320 \
--event-source-arn arn:aws:events:eu-west-1:123456789012:archive/mioapp-ordini-archive \
--event-start-time "2026-01-01T00:00:00Z" \
--event-end-time "2026-03-20T23:59:59Z" \
--destination '{
"Arn": "arn:aws:events:eu-west-1:123456789012:event-bus/mioapp-production",
"FilterArns": [
"arn:aws:events:eu-west-1:123456789012:rule/mioapp-production/ordini-vip-handler"
]
}'
# Monitorare il replay
aws events describe-replay \
--replay-name rebuild-read-model-20260320
EventBridge Lambda 소비자
// Handler Lambda Java per eventi EventBridge
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.events.ScheduledEvent;
import com.fasterxml.jackson.databind.ObjectMapper;
public class OrdiniVipHandler implements RequestHandler<ScheduledEvent, String> {
private final ObjectMapper objectMapper = new ObjectMapper();
private final VipNotificationService notificationService = new VipNotificationService();
@Override
public String handleRequest(ScheduledEvent event, Context context) {
context.getLogger().log("Evento ricevuto: " + event.getDetailType());
try {
// Deserializza il detail field
OrdineEffettuatoEvent ordine = objectMapper.convertValue(
event.getDetail(),
OrdineEffettuatoEvent.class
);
context.getLogger().log(String.format(
"Ordine VIP: %s, cliente: %s, totale: %.2f",
ordine.getOrdineId(),
ordine.getClienteId(),
ordine.getTotale()
));
// Invia notifica personalizzata al cliente VIP
notificationService.sendVipOrderConfirmation(
ordine.getClienteId(),
ordine.getOrdineId(),
ordine.getTotale()
);
return "SUCCESS";
} catch (Exception e) {
context.getLogger().log("ERRORE: " + e.getMessage());
// Rilancia per triggherare il retry di EventBridge
throw new RuntimeException("Elaborazione fallita", e);
}
}
}
// TypeScript handler per Lambda Node.js
// export const handler = async (event: EventBridgeEvent<'OrdineEffettuato', OrdineDetail>) => {
// const { ordineId, clienteId, totale } = event.detail;
// await sendVipNotification(clienteId, ordineId, totale);
// return { statusCode: 200 };
// };
EventBridge 모범 사례
- 모든 환경을 위한 맞춤형 이벤트 버스: 프로덕션, 스테이징, 개발을 위해 별도의 버스를 사용합니다. 테스트 이벤트를 프로덕션 버스로 보내지 마십시오.
- 항상 대상에 DLQ를 사용하십시오.: 각 대상에 대해 SQS 배달 못한 편지 대기열을 구성합니다. 소비자 장애 발생시 이벤트를 놓치지 않도록.
- Lambda 소비자의 멱등성: EventBridge는 최소 한 번 전달을 보장합니다. Lambda는 동일한 이벤트의 중복 수신을 처리해야 합니다.
-
이벤트 버전 관리: 항상 필드를 추가하세요.
schemaVersion세부적으로. EventBridge에는 버전 관리 메커니즘이 내장되어 있지 않습니다. 페이로드에서 이를 처리합니다. - 버스 생산별 이벤트 아카이브: 항상 보존을 사용하여 아카이브를 구성합니다. 최소 30일. 소비자에게 버그가 발생할 경우 재생을 통해 문제를 해결할 수 있습니다.
시리즈의 다음 단계
- 기사 7 – SQS, SNS, EventBridge: 선택을 위한 결정 가이드 각 특정 사용 사례에 적합한 AWS 메시징 서비스.
- 8조 - 배달 못한 편지 대기열 및 탄력성: 올바르게 구성 데이터 손실 없이 실패한 메시지를 처리하기 위한 EventBridge, SQS 및 Lambda용 DLQ.
다른 시리즈와의 연계
- 사가 패턴(제5조): EventBridge는 이상적인 메시지 버스입니다. AWS의 Choreography Saga용: 각 서비스는 EventBridge 및 다른 서비스에 이벤트를 게시합니다. 서비스는 구성된 라우팅 규칙을 통해 반응합니다.
- 아파치 카프카(시리즈 38): 온프레미스 또는 하이브리드 시스템의 경우 Kafka 및 EventBridge가 공존할 수 있습니다. 처리량이 높은 내부 메시징을 위한 Kafka, 외부 AWS 및 SaaS 서비스와의 통합을 위한 EventBridge.







