Event-Driven Architecture(EDA)는 특정 기술이 아니라 설계 패러다임입니다.
소프트웨어 컴포넌트들이 다른 컴포넌트의 직접 호출(invocation)이 아닌, 이벤트의 발생에 반응하여 실행되는 구조를 말합니다.
개념 자체는 수십 년 전부터 UI 프로그래밍, 게임 엔진, 임베디드 시스템 등에서 사용되어 왔지만, 최근 IoT·클라우드·마이크로서비스의 부상과 함께 시스템 통합(Integration)의 핵심 방법론으로 급격히 부각되고 있습니다.
이 글에서는 EDA의 아키텍처적 구성 요소를 이론적으로 정리하고, 이것이 실제 AWS 서비스와 분산 시스템 패러다임에 어떻게 매핑되는지를 연결합니다.
1. Event Processing의 세 단계
EDA를 이해하기 전에, Event Processing 자체가 무엇인지를 먼저 짚어야 합니다. 이벤트 프로세싱은 세 단계로 구성됩니다.

신용카드 사기 탐지를 예로 들면:
| 단계 | 역할 | 예시 |
| Collect | State Change(이벤트) 정보를 수집합니다 | 신용카드 사용 데이터 수집 |
| Analyze | 수집된 이벤트를 분석합니다 | 사기 패턴 탐지 (Fraud Detection) |
| React | 분석 결과에 따라 즉시 조치합니다 | 해당 카드 사용 차단 (Blocking) |
여기서 핵심은 "State Change = Event"라는 정의입니다.
이벤트는 시스템의 상태 변화 그 자체이며, 이 세 단계를 IT 서비스 형태로 효과적으로 설계하고 구성하는 것이 바로 Event-Driven Architecture(EDA)입니다.
2. Event-Driven이 의미하는 것
Unpredictability - EDA의 존재 이유
모든 이벤트가 의미 있는 것은 아닙니다. 사람의 위치가 1초마다 바뀌는 것은 대부분 무의미합니다.
EDA에서 다루는 이벤트는 비즈니스적 가치가 있는(meaningful) 이벤트입니다 - 고객의 주문, 센서의 이상 감지, 주가 변동 등.
이런 의미 있는 이벤트의 가장 중요한 특성은 언제 발생할지 예측 불가능(unpredictable)하다는 것입니다.

Event-Driven 접근법의 핵심은 이 예측 불가능한 이벤트에 대해 시스템이 자동으로, 즉시, 직접적으로 반응하는 것입니다. 사람이 개입하여 분석 코드를 짜고 설정을 바꾸는 것이 아니라, 이벤트 발생 → 핸들러 실행이 다이렉트로 연결되어야 합니다.
핵심 특성 두 가지:
- not pre-scheduled — 미리 스케줄된 것이 아닙니다.
- not activated by person or system — 사람이나 시스템이 명시적으로 활성화하는 것이 아닙니다.
세 가지 Driving Model 비교
시스템 설계에는 세 가지 구동 모델이 있습니다. 이 셋은 서로 대체 관계가 아니라 목적에 따라 혼용됩니다.
| 모델 | 트리거 | 특성 | 예시 |
| Time-Driven | 미리 정해진 스케줄 | 사전 프로비저닝됨, 주기적 실행 | DB 백업 (매일 새벽 3시), Cron Job |
| Request-Driven | 사람/시스템의 명시적 요청 | 동기적 호출, 요청-응답 패턴 | 웹 앱에서 사용자가 버튼 클릭, REST API 호출 |
| Event-Driven | 예측 불가능한 상태 변화 | 비동기적, 즉시 반응 | 센서 이상 감지 → 알람, 파일 업로드 → 썸네일 생성 |
DB 백업을 이벤트로 트리거한다면 그것은 비합리적입니다 - 백업은 무거운 작업이고, 예측 불가능한 시점에 갑자기 실행되면 시스템에 부하를 줍니다.
실제 프로덕션 시스템은 이 세 모델을 섞어서 사용합니다. AWS 환경에서도 마찬가지입니다:
- EventBridge (Event-Driven) + CloudWatch Scheduled Rules (Time-Driven) + API Gateway (Request-Driven)
3. EDA의 아키텍처 구성 요소
EDA의 아키텍처는 네 가지 구성 요소로 이루어집니다.

Event Producer (Detector)
상태 변화를 감지하고, 이를 이벤트로 만들어 Router에 Publish하는 주체입니다.
- IoT 센서가 온도 데이터를 발행하는 것
- 사용자가 파일을 업로드하면 S3가 ObjectCreated 이벤트를 발행하는 것
- 데이터베이스에 레코드가 삽입되면 Change Stream을 발행하는 것
Event Router (Mediator / Message Broker)
이벤트를 수신하고, 적절한 Channel로 라우팅하며, 구독자에게 전달하는 중앙 허브입니다. MQTT에서의 Message Broker에 해당합니다.
| 이벤트 수신 | Producer로부터 이벤트를 받습니다 |
| 라우팅 | 이벤트를 적절한 Channel(Topic)로 분류합니다 |
| 전달 | Subscribe 중인 Consumer에게 Notify합니다 |
| 관리 | Topic 생성/삭제, 구독 관리, 메시지 보존 등을 처리합니다 |
Event Channel (Topic)
Router 내부에 존재하는 논리적 통로입니다. MQTT에서의 Topic, Kafka에서의 Topic/Partition에 해당합니다. Producer는 특정 Channel에 Publish하고, Consumer는 관심 있는 Channel을 Subscribe합니다.
Event Consumer (Processor)
특정 Channel을 Subscribe하고 있다가, 이벤트가 도착하면 반응(React)하는 주체입니다. 이벤트 데이터가 input argument로 변환되어 서비스를 invoke합니다.
Publish/Subscribe 패턴의 동작

흐름을 정리하면:
- Event Consumer가 관심 있는 Channel(Topic)을 미리 Subscribe 합니다 (빨간 점선).
- Event Producer가 상태 변화를 감지하면 이벤트를 만들어 해당 Channel에 Publish 합니다 (파란 실선).
- Router(Broker)가 해당 Channel을 Subscribe 중인 Consumer에게 이벤트를 Notify 합니다.
- Consumer는 이벤트 데이터를 input argument로 받아 서비스를 실행합니다.
핵심 설계 원칙 - Loose Coupling
EDA의 가장 중요한 설계 원칙은 Producer와 Consumer가 서로를 모른다는 것입니다.
화재 탐지 시스템을 예로 들면:
- 화재 감지 센서(Producer)는 소방서 시스템(Consumer)의 존재를 알 필요가 없습니다. 그저 fire/detected라는 Topic에 이벤트를 Publish할 뿐입니다.
- 소방서 시스템(Consumer)도 어떤 센서가 이벤트를 발생시켰는지 알 필요가 없습니다. 그저 fire/detected Topic을 Subscribe하고 있다가, 이벤트가 오면 반응할 뿐입니다.
이 Loose Coupling이야말로 EDA가 SOA(Service-Oriented Architecture)의 Request-Response 패턴보다 유연한 통합(Integration)을 가능하게 하는 핵심입니다.
| SOA (Request-Driven) | EDA (Event-Driven) | |
| 호출 방식 | 서비스 A가 서비스 B를 직접 호출 | Producer가 이벤트를 발행, Consumer가 구독 |
| 결합도 | Tight Coupling (B의 주소·인터페이스를 알아야 함) | Loose Coupling (서로의 존재를 모름) |
| 확장성 | B를 교체하면 A도 수정해야 함 | Consumer를 추가/제거해도 Producer에 영향 없음 |
| 통신 방식 | 동기(Synchronous) 중심 | 비동기(Asynchronous) 중심 |
4. EDA Platform의 구성
EDA를 실현하는 플랫폼은 세 가지 핵심 기능을 제공해야 합니다.
Messaging (MQTT)
- Message Broker: 이벤트의 라우팅과 전달을 담당합니다.
- Topic & Event Management: Channel(Topic) 생성, 이벤트 필터링, 메시지 보존 정책 등을 관리합니다.
Security
- Authentication: 이 사용자가 누구인지 신원을 확인합니다. ("당신이 진짜 그 사람이 맞는가")
- Authorization: 인증된 사용자가 특정 Topic에 접근할 권한이 있는지 확인합니다. ("이 CCTV 데이터를 볼 수 있는가")
Security 없는 EDA는 프라이버시 붕괴를 의미합니다. 인증되지 않은 주체가 아무 Topic이나 Subscribe할 수 있다면, IoT 환경에서는 치명적입니다.
Service Management — 두 가지 서비스 유형
EDA 플랫폼 위에서 동작하는 서비스는 두 가지 유형으로 나뉩니다.
EDA-programmed Service (User Programming)

개발자가 직접 플랫폼의 SDK를 사용하여 Publish/Subscribe 로직을 코딩한 서비스입니다.
# 예: AWS IoT SDK를 직접 사용하는 Python 코드
import paho.mqtt.client as mqtt
client = mqtt.Client()
client.connect("broker.example.com", 1883)
client.subscribe("sensor/temperature")
client.on_message = lambda c, u, msg: process(msg.payload)
client.loop_forever()
Producer와 Consumer 모두 MQTT 프로토콜을 인지하고, 직접 Topic에 Publish/Subscribe합니다.
EDA-automated Service (Platform-Supported)

서비스 자체는 EDA를 전혀 모르고 개발된 것이지만, 플랫폼이 자동으로 이벤트 생성·서비스 활성화를 대행합니다.
서비스 B는 MQTT도, Topic도, Broker도 모릅니다. 플랫폼(예: AWS IoT Rules)이 이벤트를 감지하고, 서비스 B에 필요한 input argument를 자동으로 구성하여 호출합니다.
| 구분 | EDA-programmed | EDA-automated |
| 개발자의 EDA 인지 | SDK를 직접 사용 | EDA를 전혀 모름 |
| 유연성 | 세밀한 제어 가능 | 플랫폼이 제공하는 범위 내에서만 가능 |
| 복잡도 | 프로토콜 레벨 코딩 필요 | 설정(Configuration)만으로 연결 |
| 예시 | MQTT 클라이언트 직접 구현 | AWS IoT Rules → Lambda 트리거 |
5. AWS 서비스로 구현하는 EDA
위에서 정리한 EDA의 네 가지 구성 요소가 실제 AWS 생태계에서 어떻게 구현되는지 연결합니다.
구성 요소별 AWS 서비스
| Event Router | Amazon EventBridge, AWS IoT Core (Message Broker), Amazon SNS | EventBridge는 범용 이벤트 버스, IoT Core는 MQTT 브로커 |
| Event Channel | EventBridge Rules, SNS Topics, SQS Queues, Kinesis Streams, Kafka Topics (MSK) | 워크로드 특성에 따라 선택 |
| Event Producer | IoT 디바이스, S3 (Object Events), DynamoDB Streams, CloudTrail, 사용자 애플리케이션 | AWS 서비스 대부분이 이벤트를 발행할 수 있음 |
| Event Consumer | Lambda, ECS Task, Step Functions, SQS → Worker, SNS → HTTP Endpoint | 서버리스부터 컨테이너까지 |
EDA-automated Service의 대표 예: AWS IoT Rules
AWS IoT Rules Engine은 EDA-automated Service의 교과서적 구현입니다.
IoT Rules에서 SQL 구문으로 이벤트를 필터링하고, 조건에 맞으면 Lambda를 invoke하거나 DynamoDB에 데이터를 적재합니다. Lambda 함수는 MQTT 프로토콜의 존재를 전혀 모릅니다 — IoT Rules가 이벤트를 감지하고, input argument를 구성하여 Lambda를 호출하는 것을 자동으로 대행합니다.
Channel 선택의 트레이드오프
"Channel"이라는 추상적 개념을 구현할 때, 실제 AWS에서는 워크로드 특성에 따라 서로 다른 서비스를 선택해야 합니다.
| Channel 종류 | 구현체 특성 | 적합한 워크로드 |
| SNS | Fan-out, Push 기반, 메시지 보존 없음 | 1:N 알림, 이벤트를 여러 Consumer에게 동시 전달 |
| SQS | 큐 기반, Pull 기반, 메시지 보존 | 비동기 작업 분산, 속도 차이가 있는 Producer-Consumer 간 버퍼링 |
| Kinesis Data Streams | 순서 보장, 높은 처리량, 데이터 보존 (최대 365일) | 실시간 스트리밍, 로그 집계, 시계열 데이터 |
| Amazon MSK (Managed Kafka) | Kafka 프로토콜, 파티셔닝, Consumer Group | 대규모 이벤트 스트리밍, Replay 필요, 복잡한 토폴로지 |
| EventBridge | 스키마 기반 라우팅, 100+ AWS 서비스 통합 | AWS 서비스 간 이벤트 연결, SaaS 통합 |
6. 분산 시스템 패러다임과 EDA
Push vs Pull 모델
EDA의 이벤트 전달 방식은 Push 모델과 Pull 모델로 나뉘며, 이 선택은 시스템의 부하 특성을 근본적으로 바꿉니다.

Push 모델 (SNS, MQTT, WebSocket)
Router가 이벤트 발생 즉시 Consumer에게 능동적으로 전달합니다.
- 장점: 지연 시간(Latency)이 극소화됩니다. 실시간 반응이 필요한 시나리오에 적합합니다.
- 단점: Consumer가 처리 능력을 초과하는 속도로 이벤트가 밀려오면 백프레셔(Backpressure) 문제가 발생합니다. Consumer가 죽거나 느려지면 메시지가 유실될 수 있습니다.
- 부하 제어: Router 측에서 Rate Limiting을 걸거나, Dead Letter Queue를 설정하여 실패한 메시지를 별도로 보관합니다.
Pull 모델 (SQS, Kafka Consumer Group)
Consumer가 자신의 페이스에 맞춰 Router(Queue/Log)에서 이벤트를 능동적으로 가져옵니다.
- 장점: Consumer가 자신의 처리 속도에 맞게 소비하므로 자연스러운 Backpressure 제어가 됩니다.
- 단점: Polling 주기만큼 Latency가 증가합니다. SQS Long Polling(최대 20초 대기)으로 완화할 수 있지만, Push 모델의 즉시성에는 미치지 못합니다.
- 부하 제어: Consumer 수를 수평으로 늘리는 것(Scale-out)으로 처리량을 조절합니다.
| 비교 | Push | Pull |
| Latency | 극소 (ms 단위) | Polling 주기에 의존 |
| Backpressure | Consumer 과부하 위험 | 자연스러운 흐름 제어 |
| 메시지 보존 | 보통 없음 (Fire-and-forget) | Queue/Log에 보존 가능 |
| 확장성 | Fan-out으로 N개 Consumer에 동시 전달 | Consumer Group으로 수평 확장 |
| AWS 구현체 | SNS, IoT Core, EventBridge | SQS, Kinesis, MSK (Kafka) |
현업 패턴: SNS → SQS (Fan-out + Buffer)
실무에서는 Push와 Pull을 조합하는 것이 일반적입니다.
SNS가 이벤트를 즉시 Fan-out하고, 각 Consumer 앞에 SQS를 두어 버퍼링함으로써 Push의 즉시성과 Pull의 안정성을 모두 확보합니다.

At-most-once / At-least-once / Exactly-once
분산 시스템에서 이벤트 전달 보장 수준(Delivery Semantics)은 아키텍처 선택에 직접적 영향을 줍니다.
| 보장 수준 | 의미 | 트레이드오프 | AWS 서비스 |
| At-most-once | 최대 1번 전달. 유실 가능 | 가장 빠름, 가장 단순 | SNS (Standard), IoT Core QoS 0 |
| At-least-once | 최소 1번 전달. 중복 가능 | Consumer의 멱등성(Idempotency) 필수 | SQS, Kinesis, IoT Core QoS 1, Kafka |
| Exactly-once | 정확히 1번 전달 | 가장 비쌈, 가장 복잡 | SQS FIFO + Lambda (사실상 근사치), Kafka Transactions |
Idempotency(멱등성)은 EDA에서 가장 중요한 설계 원칙 중 하나입니다. At-least-once 환경에서는 같은 이벤트가 2번 전달될 수 있으므로, Consumer가 같은 이벤트를 2번 처리해도 결과가 동일해야 합니다.
Event Sourcing과 CQRS
EDA를 더 깊이 들어가면, 두 가지 중요한 분산 시스템 패턴과 만납니다.
- Event Sourcing: 시스템의 상태를 직접 저장하는 대신, 상태를 변화시킨 이벤트의 시퀀스를 저장합니다. 현재 상태는 이벤트를 순서대로 Replay하면 복원됩니다. (이전 스터디에서 다뤘던 Prometheus의 WAL도 개념적으로 Event Sourcing과 유사합니다.)
- CQRS (Command Query Responsibility Segregation): 쓰기(Command)와 읽기(Query)의 모델을 분리합니다. 쓰기는 이벤트로 발행하고, 읽기는 이벤트를 소비하여 별도로 구축된 읽기 전용 뷰를 조회합니다.
이 두 패턴은 EDA의 Loose Coupling 원칙과 결합하면, 대규모 분산 시스템에서 확장성(Scalability)과 가용성(Availability)을 극대화할 수 있습니다.
7. 왜 지금 EDA인가
EDA가 최근 급부상한 이유를 한 문장으로 요약하면: 미래 IT 시스템은 수많은 이질적 컴포넌트의 유연한 통합(Integration) 문제이고, EDA는 그 통합을 가장 효과적으로 해결하는 설계 패러다임이기 때문입니다.
핵심 요구사항 세 가지:
- Loosely-Coupled Integration - 컴포넌트 간 결합도를 최소화하여 유연하게 붙였다 떼었다 할 수 있어야 합니다.
- Efficient Interaction - 연결 시 오버헤드가 적고, 대량의 이벤트를 빠르게 처리할 수 있어야 합니다.
- Scalable Architecture - 수십 개든 수십만 개든, 컴포넌트 수가 늘어나도 아키텍처가 무너지지 않아야 합니다.
AWS의 거의 모든 서비스가 이벤트 중심으로 설계되어 있다는 사실은 우연이 아닙니다. EDA를 이해하면, AWS 서비스 개별이 아니라 서비스 간의 상호작용 구조 전체가 보이기 시작합니다.
'Computer Science > Architecture' 카테고리의 다른 글
| IoT 시스템 아키텍처 — 통신 모델부터 AWS까지, 이론과 실전의 연결 (0) | 2026.03.25 |
|---|---|
| 객체 지향 설계 원칙 (SOLID & GRASP)과 소프트웨어 아키텍쳐 설계 가이드라인 (2) | 2024.10.11 |
댓글