Message-Driven vs. Event-Driven Architecture
메시지 기반 (Message‑Driven) 과 이벤트 기반 (Event‑Driven) 은 비동기 통신을 통한 분산 시스템 설계 방식이다.
메시지 기반 (Message‑Driven) 는 명령 (Command) 또는 Request-Response 워크플로우 중심이며 수신자 주소를 알고 직접 메시지를 주고 받는다. 반면 이벤트 기반 (Event‑Driven) 는 상태 변화 (State Change) 를 이벤트로 정의하고 Publish-Subscribe (pub/sub) 나 Event Bus 로 브로드캐스트 (Broadcast) 하며, 소비자 목록을 알 필요 없이 느슨하게 결합된 구조로 동작한다.
두 방식은 구현 목적, 응답 실시간성, 확장성, 복잡성 등에서 차이를 보이며, 실무에서는 상호 보완적으로 병용되기도 한다.
핵심 개념
요약 정의
구분 | Message-Driven Architecture (MDA) | Event-Driven Architecture (EDA) |
---|---|---|
정의 | 명시적 수신자에게 명령 또는 요청을 메시지로 전달하는 아키텍처 스타일 | 상태 변화 등 **사실 (fact)**을 알리는 이벤트를 브로드캐스트하는 아키텍처 스타일 |
주요 흐름 | Point-to-Point 메시지 기반 요청/응답 흐름 | Publish-Subscribe 기반 비동기 반응 흐름 |
주된 목적 | 작업 실행 지시 (Command) | 상태 변화 알림 (Event Notification) |
핵심 차이 분석
항목 | Message-Driven | Event-Driven |
---|---|---|
의도 (Intent) | 수신자에게 특정 작업을 수행하라는 명시적 명령 | 상태 변화가 발생했음을 알리는 사실 기반 알림 |
메시지 타입 | Command, Request, Response | Event (fact-based) |
수신자 인식 여부 | 알고 있음 (Direct)–명시적으로 대상 지정 | 모름 (Decoupled)–브로드캐스트, 수신자는 선택적 구독 |
보통의 처리 흐름 | 1:1 메시지 라우팅 → 작업 수행 후 응답 | 1:N 이벤트 발행 → 여러 소비자가 병렬 반응 |
결합도 | 느슨하지만 명시적 수신자 존재로 일부 결합 | 느슨한 결합 (완전한 Decoupling 가능) |
순서 보장 | 큐 기반 FIFO 순서 보장 가능 | 기본적으로 순서 미보장 (설정으로 보장 가능) |
트리거 | 요청에 의해 명령 실행 | 상태 변화 발생 시 이벤트 발행 |
실행 제어 흐름 | 생산자가 통제 | 소비자가 반응 |
기술 예시 | RabbitMQ (Command Queue), JMS | Kafka (Event Log), AWS SNS |
구조 비교 다이어그램
flowchart TD subgraph MDA[Message-Driven Architecture] A1["Service A (Producer)"] -->|Command: createOrder| Q1[Queue] Q1 --> B1["Service B (Consumer)"] end subgraph EDA[Event-Driven Architecture] A2["Service A (Producer)"] -->|Event: OrderCreated| T1[Topic] T1 --> B2["Service B (Consumer)"] T1 --> C2["Service C (Consumer)"] end
- MDA: 수신자가 명시되어 있고, 메시지가 큐로 전달됨 →
Point-to-Point
- EDA: 이벤트는 브로드캐스트되며, 구독자가 선택적으로 반응 →
Publish-Subscribe
실무 혼동 방지 포인트
구분 | 설명 |
---|---|
Event ≠ Command | Event 는 발생한 일, Command 는 수행하라는 지시. 동일한 메시지 구조를 갖더라도 의미는 완전히 다름. |
EDA ≠ 비동기 메시징 | 비동기라고 모두 EDA 가 되는 것은 아님. 핵심은 상태 변화 기반의 반응형 설계인지 여부임. |
MDA 도 pub/sub 로 구현 가능 | 예: Command 를 Kafka Topic 에 게시 → Consumer 가 명령 처리. 구조는 pub/sub 지만 의도는 MDA임. |
복합 사용 가능 | MDA 와 EDA 는 상호 배타적이지 않음. 보통 Command → 처리 → Event 발행 패턴으로 같이 사용됨. |
Message-Driven vs. Event-Driven Architecture 비교
항목 | Message-Driven Architecture (MDA) | Event-Driven Architecture (EDA) |
---|---|---|
핵심 철학 | 명령 (Command)/요청 (Request) 기반 처리. 명시적 수신자에게 작업을 지시함. | 사실 (Fact)/상태 변화 (State Change) 중심. 이벤트가 발생하면 여러 수신자가 반응함. |
통신 모델 | Point-to-Point (1:1), 큐 기반 명령 전달 | Publish-Subscribe (1:N), 이벤트 브로드캐스트 |
결합도 | 상대적으로 낮음 (비동기), 그러나 수신자 인식이 필요해 일부 의존성 존재 | 매우 낮음. 이벤트 생산자는 소비자를 전혀 알 필요 없음 |
메시지 성격 | 명령, 요청, 응답 (Command/Request/Response) | 상태 변화 또는 발생된 사실 (Event/Notification) |
처리 흐름 | 정의된 워크플로우에 따라 순차적 또는 동기·비동기 처리 가능 | 비동기, 병렬 트리거 처리. 순차성 보장은 어려움. |
트리거 방식 | 명시적 메시지 호출이 트리거 | 상태 변화가 트리거되면 이벤트 발생 |
확장성 | 큐 및 컨슈머 확장으로 처리량 증가 가능, 구조적 확장에는 제약이 있음 | 구독자 추가만으로 확장 가능. 고유 이벤트 흐름 유지하며 동적 확장에 유리 |
복원력 및 재처리 | 메시지 ID, 상태 기반으로 재처리 용이 (DLQ 지원, 재시도 등) | 이벤트 중복 및 순서 처리 로직 별도 필요. 보통 Idempotency 또는 Event Replay 사용 |
장애 추적 | 메시지 ID 기반 추적 용이. 큐 단위 관찰 가능 | 이벤트 흐름이 분산되기 때문에 End-to-End Trace 도구 필수 (예: OpenTelemetry, Jaeger) |
데이터 일관성 모델 | 강한 일관성 (Strong Consistency) 설계 가능 | 최종 일관성 (Eventual Consistency) 중심. 수신자마다 상태가 비동기적으로 반영됨 |
대표 기술 스택 | RabbitMQ, ActiveMQ, Amazon SQS, Azure Service Bus | Apache Kafka, AWS SNS/EventBridge, Azure Event Grid, Google Pub/Sub |
실무 적용 예시 | 주문 처리, 워크플로우 자동화, 이메일 전송, 비동기 백오피스 작업 | 실시간 데이터 분석, 사용자 활동 이벤트, IoT, 로그 수집, 알림 시스템 등 |
운영/모니터링 복잡도 | 비교적 단순. 큐 상태, 메시지 실패율 등으로 모니터링 가능 | 이벤트 흐름 추적 복잡. 분산 트레이싱 필요. 이벤트 로스 여부 판단 어렵고 누락 방지 전략 필요 |
설계 난이도 | 비교적 단순. 송수신 정의 명확. 흐름 제어 용이 | 복잡. 이벤트 정의, 버전 관리, 처리 순서 보장, idempotency 보장 등 추가 고려 요소 다수 |
심화 분석–설계/운영 관점에서의 고려 요소
항목 | MDA 고려사항 | EDA 고려사항 |
---|---|---|
메시지 설계 | 명령 유형 정의, 메시지 순서 보장, 응답 처리 모델 포함 | 이벤트 정의, 불변성 설계, 중복 허용 처리 설계 필요 |
일관성 보장 | 트랜잭션 메시지 처리, SAGA 패턴 또는 Outbox 패턴 활용 가능 | 이벤트 기반 일관성. eventual consistency 허용, 보완을 위한 event chaining 필요 |
장애 대응 | DLQ 구성, 메시지 재시도 및 순서 재정렬 메커니즘 필요 | 이벤트 중복 제거, 순서 보장 옵션 설정, Retry → Duplicate 여부 식별 로직 필요 |
메시지 추적 | 큐 단위 추적 가능, 로그 기반 문제 진단 용이 | end-to-end 추적 어려움. 분산 트레이싱 도구 활용 필수 (ex. Jaeger + OpenTelemetry) |
테스트 전략 | Consumer 단위 단위 테스트 및 통합 테스트 비교적 용이 | 이벤트 흐름 기반 테스트 구성 어려움. Mock Event Stream, Consumer Simulation 등 필요 |
강점과 약점
구분 | Message-Driven Architecture | Event-Driven Architecture |
---|---|---|
강점 | • 명확한 통신 구조 • 높은 신뢰성 • 트랜잭션 관리 용이 • 디버깅 및 추적 용이 | • 높은 확장성 • 느슨한 결합 • 실시간 반응성 • 시스템 진화 용이 |
약점 | • 송수신자 간 결합도 • 확장성 제한 • 복잡한 라우팅 • 단일 장애점 위험 | • 이벤트 순서 관리 복잡 • 최종 일관성 문제 • 복잡한 디버깅 • 이벤트 스키마 관리 |
구조 및 아키텍처
Message-Driven Architecture 구조
graph LR A[Client] --> B[Message Producer] B --> C[Message Queue] C --> D[Message Consumer] D --> E[Service A] F[Service B] --> G[Message Queue 2] G --> H[Service C] subgraph "Message Broker" C G end
필수 구성요소:
- Message Producer: 메시지 생성 및 전송
- Message Queue: 메시지 저장 및 라우팅
- Message Consumer: 메시지 수신 및 처리
- Message Broker: 메시지 중개 및 관리
선택 구성요소:
- Dead Letter Queue: 처리 실패 메시지 관리
- Message Router: 조건부 메시지 라우팅
- Retry Mechanism: 재시도 로직
Event-Driven Architecture
graph TD A[Event Producer] --> B[Event Bus] B --> C[Event Consumer 1] B --> D[Event Consumer 2] B --> E[Event Consumer 3] C --> F[Service A] D --> G[Service B] E --> H[Analytics Service] subgraph "Event Broker" B I[Event Store] J[Event Router] end
필수 구성요소:
- Event Producer: 이벤트 발생 및 발행
- Event Bus/Broker: 이벤트 배포 및 라우팅
- Event Consumer: 이벤트 수신 및 반응
- Event Store: 이벤트 영속화 (선택적)
선택 구성요소:
- Event Sourcing: 이벤트 기반 상태 재구성
- CQRS: 읽기/쓰기 분리
- Event Mesh: 분산 이벤트 인프라
주요 원리 및 작동 원리
Message-Driven Architecture (MDA)
주요 원리:
- 메시지 단위의 통신
- 송신자 - 수신자 간 느슨한 결합
- 메시지 큐 (MQ) 또는 메시지 브로커 기반
- 재시도, ACK, DLQ(Dead Letter Queue) 등 안정성 보장
작동 원리 다이어그램:
- 메시지를 보내면 브로커 (큐) 에 쌓이고, 컨슈머가 해당 메시지를 받아 처리.
- 명령 - 응답/작업 요청 등 전통적 통신 대신, 비동기 큐가 중재함.
sequenceDiagram participant Client participant Producer participant Queue participant Consumer Client->>Producer: 요청 수행 Producer->>Queue: 메시지 전송 Consumer->>Queue: 메시지 Pull 또는 Subscribe Queue->>Consumer: 메시지 전달 Consumer->>Queue: 처리 성공 ACK
Event-Driven Architecture (EDA)
주요 원리:
- 시스템의 상태 변화 = 이벤트
- 발행/구독 (Pub/Sub) 모델 사용
- 발행자 (Producer) 는 수신자를 모름
- 다수의 소비자가 독립적으로 이벤트 처리
작동 원리 다이어그램:
- 시스템 내 상태 변화 발생 시 이벤트 생성 후 이벤트 버스에 게시.
- 이를 구독하는 다수의 컨슈머가 해당 이벤트를 감지해 각각 독립적으로 반응.
sequenceDiagram participant Producer participant EventBus participant Consumer1 participant Consumer2 Producer->>EventBus: 이벤트 발생 EventBus->>Consumer1: 이벤트 전달 EventBus->>Consumer2: 이벤트 전달 Consumer1-->>EventBus: (선택적으로 ACK) Consumer2-->>EventBus: (선택적으로 ACK)
단점과 문제점 및 해결방안
문제 유형 | 원인 및 설명 | 탐지 및 진단 | 예방 전략 | 해결 방안 및 기법 |
---|---|---|---|---|
설계 복잡성 증가 | 이벤트 흐름이 분산되고 시스템 구성요소가 많아짐 | 설계 불일치, 변경 시 영향도 분석 | 도메인 중심 이벤트 모델링 EventStorming | 아키텍처 문서화, 워크플로 자동화 |
흐름 추적 어려움 | 이벤트가 비동기적으로 다양한 소비자로 전파됨 → 요청 추적 어려움 | 로그 상관관계, 호출 체인 누락 | Correlation ID 포함, 메시지 라벨링 | OpenTelemetry, 분산 트레이싱 도구 (Jaeger 등) |
중복 메시지 | 재시도, 네트워크 실패, 브로커 재전송 등으로 중복 메시지 소비 발생 | 중복 데이터 탐지, 로그 기반 비교 | 메시지 ID/해시 기반 필터링 | Idempotent 소비자 설계, 중복 필터, 메시지 해시 적용 |
메시지 유실 | 브로커 장애, 네트워크 단절, 일시적 장애 시 메시지가 손실될 수 있음 | 브로커 로그, 큐 상태, 처리 누락 검출 | 영속 메시지 설정, 멀티 브로커 구성 | DLQ 설정, 재처리 큐 운영, 브로커 HA 구성 |
이벤트 순서 문제 | 파티셔닝된 소비자나 병렬 처리로 인해 순서가 변경될 수 있음 | 이벤트 순서 로그, 재현 시나리오 분석 | 메시지에 Sequence ID 부여, 순서 고정 큐 사용 | Kafka Offset 기반 처리, 순서 보장 전략 적용 |
데이터 일관성 불일치 | Eventual Consistency 모델로 인해 상태가 일시적으로 불일치 가능 | 상태 불일치 알람, 상태 모니터링 | 보상 트랜잭션 기반의 설계 (Saga) | Event Sourcing, CDC (Change Data Capture) |
디버깅 난이도 | 비동기 처리 로직은 동기 흐름과 달리 재현과 로깅이 복잡 | 로깅 미비, 트레이스 누락 | 테스트용 메시지 시뮬레이터 활용, 전체 흐름 로깅 활성화 | Logging 강화, DLQ 재현용 시뮬레이터, Trace Replay Tool |
테스트 어려움 | 메시지/이벤트 기반 시스템은 단위 테스트보단 통합 테스트 중심 → 시뮬레이션 요구 | 테스트 커버리지 부족, 비결정성 시나리오 발생 | 컨슈머 모킹, 메시지/이벤트 시뮬레이터 구성 | 통합 테스트 환경 구축 (e.g., TestContainers + Kafka) |
장애 탐지 지연 | 분산된 구성 요소로 인해 장애의 위치나 원인 파악이 어려움 | 로그 누락, Alert 지연 | 중앙 집중 로깅 + 모니터링 | 통합 모니터링 (Prometheus, Grafana, ELK Stack 등) |
메시지 적체 | 컨슈머 처리 속도 < 메시지 유입 속도 시 큐가 적체되어 서비스 지연 발생 | 큐 크기, 처리율, 대기 시간 모니터링 | Auto-scaling, Load Leveling 설계 | 큐 확장, 컨슈머 수 증가, 백프레셔 제어 적용 |
도전 과제
카테고리 | 도전 과제 | 원인/상황 | 영향 | 탐지 및 진단 방식 | 예방 및 해결 전략 |
---|---|---|---|---|---|
신뢰성/안정성 | 메시지/이벤트 손실 | 네트워크 장애, 브로커 중단, Ack 누락 | 데이터 유실, 흐름 중단 | 브로커 상태 모니터링, ACK 로그 분석 | 메시지 영속화 (디스크 저장), 재시도 전략, DLQ 구성 |
중복 처리 | 메시지 재전송 시 중복 처리 | QoS 1 이상 사용, 재시도 시 중복 허용 구조 | 데이터 중복 기록, 비즈니스 오류 | 이상 상태 탐지 로직, 중복 수신 로그 분석 | 메시지 ID 추적, Idempotency 키 사용, Deduplication 로직 구현 |
순서 보장 | 이벤트/메시지 순서 왜곡 | 멀티 스레드 처리, 병렬 큐, 복수 브로커 활용 | 상태 불일치, 잘못된 트랜잭션 실행 | 시퀀스 번호 모니터링, 상태 간 불일치 감지 | 파티션 키 활용, 순서 큐 구성, 메시지 헤더 시퀀싱, 이벤트 버퍼링 |
일관성 보장 | 분산 트랜잭션 처리 어려움 | 서비스 간 독립 처리, 원자성 부족 | 데이터 무결성 깨짐, 불일치 상태 발생 | 상태 불일치 분석, 상태 확인 작업 | Saga 패턴, 보상 트랜잭션, Outbox 패턴, Eventually Consistent 설계 적용 |
관찰 가능성 | 이벤트 흐름 추적의 어려움 | 비동기 처리 + 이벤트 확산 → 인과 관계 파악 복잡 | 장애 진단 지연, 성능 병목 추적 어려움 | 분산 추적 시스템, 로그/메트릭 연동 분석 | Correlation ID 삽입, OpenTelemetry, Jaeger, Zipkin 등 활용 |
스키마 진화 | 이벤트 구조 변경에 따른 호환성 이슈 | 메시지/이벤트 필드 추가/삭제, 버전 불일치 | 소비자 에러, 통신 오류 | 스키마 유효성 검사, 호환성 테스트 | Schema Registry 도입, 버전 관리 전략, Avro/Protobuf 기반 호환 설계 |
보안/컴플라이언스 | 메시지/이벤트 보호 및 인증 문제 | 분산 경계, 브로커 - 컨슈머 간 전송 보안, 인증 미비 | 민감 데이터 노출, 규정 위반 | 감사 로그, 보안 이벤트 추적 | 메시지 암호화, OAuth2 인증, ACL 설정, Zero Trust 설계 적용 |
팀 간 협업/거버넌스 | 서비스 간 스키마 및 이벤트 관리 문제 | 서비스 단위로 분산 개발, 계약 부재, 의사소통 단절 | 중복 개발, 비호환 이벤트 설계 | API/이벤트 문서 리뷰, 아키텍처 검토 | API First, 표준화된 메시지 컨벤션, ADR 관리, 이벤트 명세 중심의 협업 프로세스 |
모니터링/운영 | 장애 대응 및 지표 부족 | 분산 컴포넌트 모니터링 누락, 지표 비통합 | 장애 징후 탐지 지연, 복구 시간 증가 | 지연/에러율 모니터링, DLQ 확인 | 메트릭 수집 (Prometheus), Alerting Rule 정의, 중앙 집중 로그 수집 (ELK/EFK 등) |
테스트/검증 | 이벤트 흐름 테스트의 어려움 | 컨슈머/프로듀서 간 계약 불명확, 테스트 환경 미흡 | 이벤트 누락/불일치로 인한 기능 실패 | 컨트랙트 기반 테스트 도입, 이벤트 시뮬레이션 | Consumer-Driven Contract Testing, 테스트 더블 (Double) 및 샌드박스 환경 구축 |
실무 사용 예시
산업 분야 | 시스템 유형 | 활용 아키텍처 유형 | 주요 목적 | 기대 효과 | 주요 기술 구성 |
---|---|---|---|---|---|
전자상거래 | 주문 처리 시스템 | MDA → EDA 혼합형 | 주문 → 결제 → 배송의 워크플로우 분리 및 상태 변화 후 다중 시스템 동기화 | 확장성, 처리 신뢰성, 실시간 반응 | RabbitMQ, Kafka, Redis |
금융 | 거래 처리 및 분석 시스템 | MDA (트랜잭션 처리), EDA (사후 분석) | 거래 승인 → 계좌 업데이트 후 이벤트 기반 분석/리스크 처리 | 신뢰성, 실시간 탐지, 규제 대응 | JMS, EventStore, Lambda |
물류 | 배송 추적/관리 시스템 | EDA 중심 | 배송 상태 변화에 따른 이벤트를 실시간 처리 및 분석 연계 | 가시성 확보, 사용자 경험 향상 | Kafka, AWS SNS, Webhook |
IoT/제조 | 센서 기반 데이터 처리 | EDA 중심 | 대규모 센서 이벤트 스트리밍 처리 및 예측 정비 | 운영 효율성, 지능형 유지보수 실현 | Kafka, MQTT, Flink |
게임 | 멀티플레이어 실시간 게임 | EDA 중심 | 플레이어 이벤트 발생 → 분석, 개인화, 랭킹, 추천 시스템 연동 | 실시간 반응, 사용자 경험 최적화 | Kafka, Redis Streams, WebSocket |
마케팅/알림 | 푸시 알림, 이벤트 기반 마케팅 | EDA + Pub/Sub | 알림, 캠페인, 마케팅 자동화 트리거 처리 | 실시간성, 개인화, 운영 자동화 | AWS SNS/SQS, Firebase, Webhook |
스마트 시티 | 환경/교통 데이터 수집 | EDA + CEP | 실시간 센서/트래픽 이벤트 분석 및 정책 트리거 | 정책 대응 속도 향상, 비상 상황 탐지 | Kafka, Apache Flink, Complex Event Processing |
엔터프라이즈 | 마이크로서비스 간 통신 | MDA + EDA 혼합형 | 비즈니스 프로세스 → 메시지 처리 / 상태 변화 → 이벤트 반응 | 유연한 통합, 독립 배포, 확장성 확보 | Kafka + RabbitMQ, Outbox Pattern |
활용 사례
사례 1: 온라인 쇼핑몰의 주문 처리 시스템
아키텍처 적용 방식:
- 주문 등록 → 결제 승인 → 재고 차감 → 배송 예약 과정을 각각 분리된 서비스로 구성
- 각 단계는 메시지 기반 (MDA) 으로 연결, 이벤트 발생 시 각 서비스는 이벤트를 수신하여 동작
시스템 구성
graph TD A[Order Service] -->|Message| B[Payment Service] B -->|Message| C[Inventory Service] C -->|Message| D[Delivery Service] D -->|Event| E[Notification Service]
Workflow 설명:
- 사용자가 주문을 생성하면 메시지가 결제 서비스로 전달됨.
- 결제 완료 후 재고 차감 요청 메시지 전송.
- 재고 확인 후 배송 예약 요청.
- 최종 배송 등록 이벤트 발생 → 이벤트 기반 (Notification) 으로 사용자 알림.
Message-Driven 없을 경우 문제점:
- 상태 전이 실패 시 복구 어려움.
- 재시도/보장된 순서 처리 불가능.
Event-Driven 없이 Notification 처리 시 문제점:
- Notification Service 가 상태를 직접 폴링하거나 상태 공유 구조 필요 → 복잡성 증가.
구현 예시:
|
|
위 코드는 주문 생성 후 결제 서비스로 메시지를 큐에 넣는 구조. 결제 서비스는 이를 소비하여 처리하게 된다. 확장성과 안정성 확보에 유리하다.
사례 2: 대형 이커머스의 주문 처리 시스템
시스템 구성: 주문 서비스 → 메시지 브로커 (RabbitMQ) → 재고 서비스, 결제 서비스
아키텍처 다이어그램:
sequenceDiagram participant User participant OrderService participant MQ as RabbitMQ participant InventoryService participant PaymentService User->>OrderService: 주문 요청 OrderService->>MQ: 주문 메시지 발행 MQ->>InventoryService: 주문 메시지 전달 MQ->>PaymentService: 주문 메시지 전달 InventoryService-->>OrderService: 재고 처리 결과(비동기) PaymentService-->>OrderService: 결제 결과(비동기)
Workflow: 주문 발생 → 메시지 발행 → 재고/결제 서비스 각각 독립적으로 처리 및 알림
역할: 동시성 보장, 이벤트/비동기 기반 병렬처리, 확장성 확보
유무 차이점: 메시지 기반/이벤트 기반 아키텍처가 없을 경우 주문 폭주 상황에서 서비스 지연, 장애 확산이 잦음.
구현 예시:
|
|
각 함수에 주석으로 메시지 발행/수신의 위치와 역할, 비동기 큐 소비를 명확하게 구분
사례 3: 전자상거래 주문 처리 시스템
시스템 구성:
- 전자상거래 플랫폼에서 Message-Driven 과 Event-Driven 아키텍처를 함께 활용한 하이브리드 접근법을 적용했다.
graph TB subgraph "프론트엔드" A[웹/모바일 앱] end subgraph "API Gateway" B[API Gateway] end subgraph "Message-Driven 영역" C[주문 서비스] D[결제 서비스] E[재고 서비스] F[배송 서비스] Q1[주문 처리 큐] Q2[결제 큐] Q3[배송 큐] end subgraph "Event-Driven 영역" G[이벤트 버스] H[알림 서비스] I[분석 서비스] J[추천 서비스] K[재고 추적 서비스] L[고객 서비스] end subgraph "데이터 저장소" M[(주문 DB)] N[(결제 DB)] O[(재고 DB)] P[(이벤트 스토어)] end A --> B B --> C C --> Q1 Q1 --> D D --> Q2 Q2 --> E E --> Q3 Q3 --> F C --> G D --> G E --> G F --> G G --> H G --> I G --> J G --> K G --> L C --> M D --> N E --> O G --> P
Workflow:
- Message-Driven 처리 흐름:
- 주문 생성: 고객이 주문을 생성하면 주문 서비스가 주문 정보를 검증
- 재고 확인: 주문 서비스가 재고 서비스에 메시지를 보내 재고 확인 요청
- 결제 처리: 재고 확인 완료 후 결제 서비스에 결제 처리 메시지 전송
- 배송 요청: 결제 완료 후 배송 서비스에 배송 요청 메시지 전송
- Event-Driven 처리 흐름:
- 이벤트 발행: 각 단계 완료 시 이벤트 발행 (주문 생성됨, 결제 완료됨 등)
- 병렬 처리: 여러 서비스가 동일 이벤트를 동시 구독하여 처리
- 실시간 반응: 알림, 분석, 추천 등이 실시간으로 동작
역할:
- Message-Driven Architecture 역할:
- 핵심 비즈니스 로직의 순차적 처리 보장
- 트랜잭션 일관성 유지
- 중요한 업무 프로세스의 신뢰성 확보
- Event-Driven Architecture 역할:
- 부가 서비스들의 확장성 제공
- 시스템 간 느슨한 결합 달성
- 실시간 반응성 확보
아키텍처 유무에 따른 차이점:
- 적용 전 (단순 REST API):
- 모든 서비스가 동기적으로 호출되어 응답 시간 증가
- 부가 서비스 장애가 핵심 주문 프로세스에 영향
- 새로운 기능 추가 시 기존 코드 수정 필요
- 적용 후 (하이브리드 아키텍처):
- 핵심 프로세스와 부가 서비스의 독립적 처리
- 부가 서비스 장애가 주문 프로세스에 미치는 영향 최소화
- 새로운 서비스 추가 시 이벤트 구독만으로 연동 가능
- 평균 주문 처리 시간 40% 단축, 시스템 가용성 99.9% 달성
구현 예시:
|
|
MDA (Message-Driven Architecture) & EDA (Event-Driven Architecture) 혼합 아키텍처
MDA+EDA 혼합 아키텍처 도입 전략
상황 | 이유 |
---|---|
명령형 워크플로우 필요 | 주문 → 결제 → 재고 차감 → 배송 등 명확한 순서가 존재 |
상태 변화 기반 이벤트 발생 필요 | ’ 결제 완료됨 ‘, ’ 배송 시작됨 ’ 등의 이벤트 발생 필요 |
시스템 간 통합이 복잡함 | 일부 서비스는 명령 기반, 일부는 상태 반응 기반으로 구성됨 |
확장성과 디커플링 모두 필요 | 서비스 간 동기화 및 반응형 처리의 동시 구현 필요 |
전략적 구성 원칙
전략 | 설명 |
---|---|
Command = Message (MDA) | 명령적 흐름은 메시지 큐 기반 (e.g. 결제 요청, 배송 예약 등) |
State Change = Event (EDA) | 상태 변화는 이벤트로 브로드캐스트 (e.g. 배송 완료 이벤트) |
도메인 경계 기반 메시지/이벤트 분리 | 메시지는 요청 (Command), 이벤트는 상태 (State) 변화 중심으로 설계 |
비즈니스 로직은 메시지 기반, 리액션은 이벤트 기반 | 주 흐름은 메시지 처리로, 후속 작업 (알림, 분석 등) 은 이벤트 처리로 분리 |
메시지 우선, 이벤트 보완 구조 적용 | 강한 신뢰성과 제어가 필요한 영역은 메시지, 반응형은 이벤트 |
도입 시 아키텍처 구성
flowchart TD A[Order Service] -->|Command| B["Message Broker (RabbitMQ)"] B --> C[Payment Service] C -->|Event: PaymentCompleted| D["Event Bus (Kafka)"] D --> E[Shipping Service] D --> F[Notification Service] D --> G[Analytics Service]
- Message Broker: Command 중심 워크플로우 조율
- Event Bus: 상태 변화 이벤트 전파
- 결제 완료 이벤트가 여러 서비스로 전파됨 (Shipping, Notification, Analytics)
적용 시 고려사항
고려항목 | 설명 | 권장 기술/패턴 |
---|---|---|
메시지/이벤트 명확한 구분 | Command 는 의도 (Intent), Event 는 결과 (Result) | CQRS 패턴 |
메시지 처리 보장 | 중복 처리 방지, 실패 보상 등 | Idempotent Consumer, DLQ |
이벤트 흐름 추적 | 이벤트 경로 추적 가능해야 함 | OpenTelemetry, Jaeger |
트랜잭션 분산 처리 | 원자성 보장 안 되는 경우 처리 방식 명확화 | Saga Pattern |
데이터 일관성 확보 | Command-Event 순서가 비동기인 경우 주의 | Outbox Pattern |
이벤트 처리 순서 | 순서 중요 시 파티션 키 기반 처리 필요 | Kafka 파티션 사용 |
테스트 전략 수립 | 메시지 시뮬레이션, 이벤트 발행 모킹 | Contract Test, Simulation Broker |
혼합 아키텍처의 실무 적용 예시
시스템 | MDA 역할 | EDA 역할 | 도입 효과 |
---|---|---|---|
주문 시스템 | 주문 등록, 결제 요청 | 결제 완료 → 배송 시작, 알림, 분석 | 명확한 흐름 + 반응형 서비스 분리 |
IoT 시스템 | 디바이스 제어 명령 | 센서 데이터 수신 이벤트 | 명령형 + 대규모 이벤트 수집 |
금융 시스템 | 대출 심사 요청 | 심사 완료 이벤트 → 상태 변경 및 통보 | 신뢰성 + 실시간 대응 |
교육 플랫폼 | 시험 시작 명령 | 시험 완료 → 결과 발표, 이메일 발송 | 명확한 트리거 + 다양한 이벤트 소비자 |
기술 조합 예시
목적 | 메시지 시스템 (MDA) | 이벤트 시스템 (EDA) |
---|---|---|
명령/요청 워크플로우 | RabbitMQ, AWS SQS, ActiveMQ | - |
상태 변화 이벤트 전파 | - | Apache Kafka, AWS EventBridge |
복잡한 트랜잭션 처리 | Saga Orchestrator with Message Bus | Choreography 기반 Event Flow |
유저 인터페이스 반응성 | - | WebSocket, SSE, Kafka Stream |
이벤트 저장 | - | Event Sourcing, Change Data Capture |
실제 메시지 / 이벤트 구조 설계 예시 (JSON Schema)
Message-Driven (Command) 메시지 예시
|
|
- 의도: 송신자가 수신자에게
CreateInvoice
작업을 명령 - 전송 대상: 특정 컨슈머 (
InvoiceService
)
Event-Driven (Event) 메시지 예시
|
|
- 의도: 주문이 생성되었다는 사실 전달
- 소비자:
InvoiceService
,AnalyticsService
,NotificationService
등 다수
MDA / EDA 구조 예시 코드 (Python & Node.js)
MDA - Python (RabbitMQ)
|
|
|
|
EDA - JavaScript (Kafka with Node.js)
|
|
|
|
CQRS + Event Sourcing 기반 혼합 아키텍처 흐름도
sequenceDiagram actor User participant API as API Gateway participant CMD as Command Handler participant DB as Write DB participant EventBus as Event Bus participant ReadModel as Read DB (Projection) participant Invoice as Invoice Service User ->> API: HTTP POST /orders API ->> CMD: CreateOrderCommand CMD ->> DB: Persist Order (Event Sourced) CMD -->> EventBus: Publish OrderCreatedEvent EventBus -->> Invoice: OrderCreatedEvent EventBus -->> ReadModel: Project OrderView Note over ReadModel: Eventually consistent
- 사용자가 주문 생성 요청 (Command)
- Command Handler가 상태 변경 처리 → 이벤트 저장소에 기록
OrderCreatedEvent
를 Event Bus에 발행- InvoiceService 등은 이벤트를 기반으로 후속 작업
- Read Model은 Projection 하여 조회 모델을 구성 (CQRS)
Outbox 패턴 기반 MDA ↔ EDA 브리지 구현
Outbox 패턴은 트랜잭션 경계 내에서 메시지 저장 → 이후 메시지를 브로커에 발행하는 전략으로, MDA 의 안정성과 EDA 의 반응성을 연결하는 주요 패턴이다.
아키텍처 흐름 개요
flowchart TD A[Service A: Command Handler] -->|DB 트랜잭션| B[(Order Table + Outbox Table)] B --> C["Outbox Poller (CDC or Cron)"] C --> D[Event Publisher] D --> E[Kafka/EventBridge] E --> F["Consumer Services (Invoice, Analytics, Notification)"]
- Write 트랜잭션
- 서비스는 DB 트랜잭션 안에서 도메인 데이터와 함께 Outbox Table 에 이벤트를 기록한다.
- Outbox Poller 또는 CDC
- 별도 프로세스가 outbox 테이블을 주기적으로 스캔하거나 CDC 를 통해 변경 감지.
- Event 발행기
- 폴링된 메시지를 Kafka 나 EventBridge 등에 EDA 이벤트로 게시.
- 다수의 Consumer 가 이벤트 구독
Outbox Table 구조 예시
컬럼명 | 설명 |
---|---|
id | UUID |
aggregate_id | 관련 도메인 ID |
type | 이벤트 타입 (ex: OrderCreated ) |
payload | JSON 포맷의 이벤트 데이터 |
status | PENDING , SENT , FAILED 등 |
created_at | 생성 시각 |
Python 예시 (SQLAlchemy + Kafka)
|
|
MDA (Message-Driven Architecture) & EDA (Event-Driven Architecture) 혼합 아키텍처 With Kafka
아키텍처적으로 설계 관점과 메시지 사용 방식이 달라야 하며, Kafka 가 본질적으로 Event-Driven 친화적인 플랫폼이라는 점을 이해하고, MDA 스타일에 맞게 보완 설계가 필요하다.
Kafka 하나로 MDA & EDA 처리하는 방식 요약
아키텍처 유형 | Kafka 적용 방식 | 설명 |
---|---|---|
MDA (명령 기반) | Point-to-Point 방식 구현 (Consumer Group 활용) | 특정 명령을 하나의 서비스가 처리하도록 설정 (1:1 처리 구조) |
EDA (이벤트 기반) | Pub/Sub 방식 구현 (Consumer Group 없이 독립 구독) | 동일 이벤트를 여러 서비스가 독립적으로 병렬 반응 (1:N 구조) |
MDA with Kafka–구현 방법
Kafka 는 원래 Pub/Sub 구조지만, Consumer Group을 활용하면 MDA 의 Point-to-Point 스타일로 구현할 수 있다.
flowchart LR Producer -->|command: createInvoice| KafkaTopic KafkaTopic -->|ConsumerGroup: invoice-service| ConsumerA
- 동일 Consumer Group 내에서는 단일 인스턴스만 메시지를 소비
- 즉, Kafka 에서도 MDA 스타일의 명령 처리 가능
EDA with Kafka–구현 방법
Kafka 본연의 Event-Driven 처리. 여러 Consumer Group 이 각각 이벤트를 수신하고 처리 가능하다.
flowchart LR Producer -->|event: OrderCreated| KafkaTopic KafkaTopic -->|ConsumerGroup: invoice| InvoiceService KafkaTopic -->|ConsumerGroup: notification| NotificationService KafkaTopic -->|ConsumerGroup: analytics| AnalyticsService
- 이벤트는 모든 ConsumerGroup 에 복제 전파됨
- 병렬 반응 가능하며, 완전한 Pub/Sub 패턴 구현
Kafka 기반 MDA & EDA 혼합 예시 구조
flowchart TD API[User Command API] API -->|Command| KafkaCmd[Kafka: order.commands] KafkaCmd -->|Group: order-handler| OrderService OrderService -->|Event| KafkaEvt[Kafka: order.events] KafkaEvt --> InvoiceService KafkaEvt --> AnalyticsService KafkaEvt --> NotificationService
order.commands
: Command Topic (MDA 역할)order.events
: Event Topic (EDA 역할)
구현 시 주의할 점
항목 | 주의사항 |
---|---|
명령 vs 이벤트 토픽 분리 | MDA 스타일은 command.topic , EDA 스타일은 event.topic 으로 분리하는 것이 좋음 |
역할 분리 명확히 | CommandConsumer , EventConsumer 역할 분리해서 구현 |
Idempotency 필수 | Kafka 는 중복 수신 가능 → 컨슈머는 반드시 중복 처리 방어 |
Dead Letter Queue (DLQ) | MDA 의 경우 실패 메시지는 DLQ 처리 구조 반드시 설계 |
Schema Registry 활용 | Avro/JSON 스키마를 등록해 구조 변경 관리 필요 |
Kafka 기반 MDA / EDA 분리 구현 예시 (Python)
기본 전제:
- Kafka 서버 주소:
localhost:9092
- Command Topic:
order.commands
- Event Topic:
order.events
- Group ID:
- MDA Consumer:
order-command-handler
- EDA Consumers:
invoice-service
,notification-service
- MDA Consumer:
Command Producer (MDA 용)
|
|
Command Consumer (MDA 처리기: 1:1 처리)
|
|
Event Consumer (EDA: 다수 컨슈머)
Invoice Service:
|
|
Notification Service:
|
|
실행 순서 요약
command_consumer.py
→ MDA Consumer 실행invoice_consumer.py
,notification_consumer.py
→ EDA Consumers 실행send_command.py
→ 명령 전송- 흐름:
order.commands
→ Order 처리- 처리 후
order.events
로 Event 발행 - Event 는 여러 서비스에서 병렬로 소비됨
아키텍처 흐름 시각화
sequenceDiagram participant A as send_command.py participant B as command_consumer.py participant Kafka1 as Topic: order.commands participant Kafka2 as Topic: order.events participant C as invoice_consumer.py participant D as notification_consumer.py A->>Kafka1: Command: CreateOrder Kafka1->>B: MDA Consumer (Command 처리) B->>Kafka2: Event: OrderCreated Kafka2->>C: Invoice 처리 Kafka2->>D: Notification 처리
Command vs. Event 구분 기준 및 메시지 라우팅 전략
구분 기준
항목 | Command (명령) | Event (이벤트) |
---|---|---|
의도 | 행동을 유도 (Do something) | 사실을 알림 (Something happened) |
시간 | 미래 (미실행 상태) | 과거 (이미 발생함) |
수신자 | 단일 수신자 (명확한 담당자) | 0 개 이상 수신자 (누가 받을지는 모름) |
응답 필요 여부 | 일반적으로 Yes (결과 필요) | 일반적으로 No (단방향 브로드캐스트) |
구성 요소 | Command ID , Target , Payload , Expected Result | Event ID , Event Type , Timestamp , Payload |
라우팅 전략
전략 유형 | 설명 | 예시 |
---|---|---|
명령 라우팅 (Command Routing) | 큐 이름이나 라우팅 키로 명시적으로 라우팅. 보통 Point-to-Point 방식 사용 | invoice.create.command → InvoiceService 큐에 직접 전달 |
이벤트 브로드캐스트 | 주제 기반 토픽에 게시. 관심 있는 소비자가 구독 | order.events → 여러 서비스가 동시에 반응 |
EventType 기반 라우팅 | 이벤트의 type 필드 기반으로 동적 라우팅 수행 | Kafka topic 내부에서 "event_type" == "OrderCreated" 필터 |
Contextual Routing | 메시지에 포함된 도메인 정보나 컨텍스트를 기준으로 라우팅 | “VIP 고객 이벤트만 분석 서비스로 전파 " |
메시지 라우팅 예시 (Kafka Stream)
is_vip == true
→ Analytics 서비스로 전송event_type == OrderCreated
→ Invoice, Notification, OrderHistory 모두 수신
Kafka Streams, Flink, NiFi 등을 이용하여 내용 기반 라우팅을 손쉽게 구현할 수 있음.
실무에서 효과적 적용을 위한 고려사항
카테고리 | 고려 항목 | Message-Driven Architecture (MDA) | Event-Driven Architecture (EDA) | 권장 사항 및 전략 |
---|---|---|---|---|
1. 메시지/이벤트 설계 | 메시지/이벤트 정의 | 명시적 메시지 타입 (Command/Request/Response 구분) | 이벤트 의미 중심 정의 (상태 변화, 도메인 사상 중심) | 변하지 않는 계약 기반 설계 (Contract), 타입 명확화, 이벤트 이름 표현 일관성 유지 |
스키마 관리 | 명시적 메시지 계약 관리 | 이벤트 스키마의 하위 호환성 및 버전 관리 필요 | JSON Schema / Protobuf + Schema Registry / AsyncAPI 활용 | |
2. 장애 및 실패 처리 | 실패 메시지 처리 | DLQ(Dead Letter Queue), Retry, Timeout 처리 | 중복 이벤트 처리, 순서 보장, 보상 트랜잭션 필요 | Idempotency Key 적용, 메시지 순서 처리 (Partition Key, Session) |
장애 전파 제어 | 처리 실패 시 오류 큐 분리 및 재처리 중심 | 이벤트 컨슈머 오류 시에도 전체 시스템 영향 최소화 | Circuit Breaker, Retry with Backoff, Outbox Pattern 적용 | |
3. 트랜잭션 관리 | 일관성 처리 | 큐 기반 트랜잭션 처리 필요 | 이벤트 흐름 기반 일관성 설계 (Eventually Consistent) | Saga 패턴 활용 (로컬 트랜잭션 + 보상 로직 분리), Outbox + Polling 기반 데이터 연동 |
4. 운영/모니터링 | 지표 수집 | 큐 깊이, 처리 지연, 에러율 중심 | 이벤트 발생률, 처리 지연, 누락 이벤트 탐지 | Prometheus + Grafana, Alerting Rule, DLQ 모니터링 |
흐름 추적 | 메시지 ID 및 Correlation ID 기반 흐름 추적 | 이벤트 흐름 추적 및 인과 관계 분석 필요 | Distributed Tracing (OpenTelemetry, Jaeger, Zipkin 등) 적용 | |
5. 테스트 전략 | 계약 기반 테스트 | Producer/Consumer 간 명시적 메시지 계약 필요 | Event Flow 기반 테스트 및 상태 전이 검증 | Consumer-Driven Contract Test, Schema Validation Test |
6. 팀/조직 구조 | 서비스 소유권 및 거버넌스 | 서비스 단위로 메시지 주고받는 명확한 책임 구조 | 이벤트 발행자/구독자 간 소유권 불분명 가능성 있음 | Conway’s Law 기반 서비스 - 팀 정렬, 이벤트 명세에 대한 거버넌스 체계 수립 |
최적화를 위한 고려사항
카테고리 | 최적화 대상 | 메시지 기반 아키텍처 (MDA) | 이벤트 기반 아키텍처 (EDA) | 공통 권장 전략 및 설명 |
---|---|---|---|---|
1. 성능 | 처리량 & 지연 시간 | 배치 처리, 큐 기반 병렬 소비 | 스트림 기반 처리, 이벤트 파이프라인 분산 처리 | 파티셔닝, 병렬 소비자 구성, 비동기화 |
2. 저장소 | 스토리지 효율성 | 메시지 압축 (Gzip, Snappy), TTL 기반 자동 삭제 설정 | 이벤트 압축 + 장기 아카이빙 (예: S3, Glacier) | 압축 알고리즘 적용, 저장 주기 분리 |
3. 네트워크 | 대역폭 효율성 | 메시지 배칭 및 경량 메시지 포맷 사용 | 이벤트 배칭, 미니멀 이벤트 페이로드 설계 | 배치 전송, 프로토콜 최소화 (e.g., Protobuf) |
4. 메모리 | 메모리 사용 최적화 | 메시지 캐시 활용 (Redis, LRU 등), 큐 기반 버퍼링 | 스트림 버퍼 조절, 이벤트 리플레이 캐시 | 적응형 버퍼 크기 조정, 백프레셔 적용 |
5. 확장성 | 수평 확장 | 브로커 클러스터 구성, Consumer 확장 | 이벤트 버스 확장, Auto-scaling 기반 소비자 구성 | 클라우드 네이티브 Auto-scaling, 분산 트래픽 라우팅 |
6. 정확성 | 중복 방지 & 유실 대응 | 메시지 ID 추적, 오프셋 관리, 재처리 시 idempotent 설계 | 이벤트 중복 필터링, Exactly-once 처리 (Kafka EOS 등) | 재시도 + 중복 제거 전략, 메시지 추적 ID 기반 처리 |
7. 지연 최적화 | 지연 최소화 | 경량 메시지 포맷 (JSON → Protobuf), 브로커 처리 최적화 | 실시간 이벤트 전달 + 스트리밍 최적화 (Kafka, Flink 등) | 경량화, 실시간 처리 우선 순위 설계 |
8. 운영 관리 | 리소스 활용도 | 큐 대기 시간, DLQ 메시지 수, 처리율 등 메트릭 기반 운영 | 이벤트 처리 실패율, 라그 (Lag), 소비자 상태 추적 | Prometheus + Grafana 모니터링, Alerting 구성 |
9. 장애 대응 | 오류 회복력 | DLQ, Retry Policy, Circuit Breaker 설정 | 이벤트 재처리 및 재전파, 컨슈머 복구 전략 | 자동 Failover, 상태 기반 재처리 설계 |
주목할 내용
카테고리 | 항목 | 설명 | 관련 아키텍처 |
---|---|---|---|
** 설계 원칙** | Idempotency | 동일 메시지 반복 처리 시 중복 효과 방지. 정합성과 안전성을 위한 핵심 속성 | MDA, EDA |
순서 보장 (Ordering) | 메시지 순서대로 처리 보장 필요 시 파티션, 키, 세션 단위로 설계 (e.g., Kafka partition key) | MDA | |
CQRS 패턴 | Command(쓰기) 와 Query(읽기) 모델 분리로 확장성 및 성능 최적화 | EDA 중심 | |
** 패턴과 전략** | Saga Pattern | 분산 트랜잭션을 보상 트랜잭션으로 분리 관리하여 롤백 없이 일관성 유지 (비동기 트랜잭션 제어) | MDA, EDA |
Event Sourcing | 시스템 상태를 이벤트 로그로 저장, 재생성 가능한 상태 복원 및 감사 추적 가능 | EDA | |
** 인프라/플랫폼** | Apache Kafka | 고성능 이벤트 스트리밍 플랫폼, Pub/Sub 및 로그 기반 저장 포함 | MDA, EDA |
RabbitMQ | 전통적인 메시지 큐, 복잡한 라우팅 및 보증 수준 처리에 적합 | MDA | |
AWS SQS/SNS | 클라우드 기반 메시징 서비스, 확장성과 관리 편의성 제공 | MDA, EDA | |
** 운영/모니터링** | Dead Letter Queue (DLQ) | 실패 메시지 격리 보관 큐, 장애 원인 분석 및 재처리 기반 | MDA, EDA |
Distributed Tracing | 마이크로서비스 및 메시지 기반 시스템 간 흐름 시각화 및 성능 병목 분석 (예: Jaeger, OpenTelemetry) | MDA, EDA | |
메트릭 수집 | 처리량, 지연, 실패율 등의 지표 수집으로 SLA 및 성능 관리 | MDA, EDA | |
로그 집계 (Logging) | 구조화된 메시지 기반 로그를 통해 디버깅 및 이벤트 트레킹 가능 | MDA, EDA | |
** 확장성과 복구성** | 수평 확장성 (Scalability) | 컨슈머/리스너 개별 확장이 용이하며 메시지 큐 기반 구조가 동적 스케일아웃에 적합 | MDA, EDA |
이벤트 기반 민첩성 | 시스템의 상태 변화에 따라 리액티브하게 동작하여 민첩성 확보 | EDA | |
Event Store | 이벤트의 영속적 저장을 통한 재처리, 복구, 비즈니스 감사 가능 | EDA |
반드시 학습해야할 내용
카테고리 | 주제/영역 | 핵심 항목 | 설명 |
---|---|---|---|
1. 이론적 기반 | 분산 시스템 이론 | CAP Theorem | Consistency, Availability, Partition Tolerance 간의 트레이드오프 원리 |
최종 일관성 (Eventually Consistent) | 분산 환경에서 강한 일관성 대신 허용되는 지연된 동기화 모델 | ||
ACID vs BASE | 전통 트랜잭션 모델과 느슨한 일관성 모델의 비교 | ||
2. 메시징 패턴 | 통신 패턴 | Request-Reply | 동기적 요청 - 응답 처리 구조 (예: HTTP, RPC) |
Publish-Subscribe | 비동기 이벤트 기반 다중 수신자 구조 (예: Kafka Topics) | ||
Message Queue | FIFO 기반의 메시지 큐 구조 (예: RabbitMQ Queue) | ||
3. 이벤트 아키텍처 | 이벤트 중심 설계 | Event Sourcing | 모든 상태 변경을 이벤트로 저장해 재구성 가능 |
CQRS | 명령 (Command) 과 조회 (Query) 모델 분리 | ||
Event Store | 이벤트 영속화를 위한 저장소 (예: Kafka, EventStoreDB) | ||
4. 트랜잭션 처리 | 분산 트랜잭션 관리 | Saga Pattern | 보상 트랜잭션 기반의 분산 트랜잭션 처리 |
Idempotent Design | 재시도 시 중복 처리를 방지하는 설계 전략 | ||
Retry / DLQ | 실패 메시지 재처리 및 대체 큐 전략 (Dead Letter Queue) | ||
5. 구현 프레임워크 | 메시징 브로커 구성 요소 | RabbitMQ / Kafka | 대표적인 메시징 시스템, 큐/토픽 기반 메시지 처리 |
Event Bus | 이벤트 기반 통합 시스템의 중심 통신 채널 | ||
Service Mesh | 메시지 기반 마이크로서비스 간 통신 관리 (예: Istio) | ||
API Gateway | 클라이언트 요청을 내부 서비스로 라우팅하는 진입 지점 | ||
6. 운영 및 관찰성 | 시스템 관찰성 구성 | 분산 트레이싱 (Tracing) | 서비스 간 호출 관계 추적 (예: OpenTelemetry, Jaeger) |
메트릭 수집 (Metrics) | 처리량, 지연시간 등 시스템 지표 모니터링 (예: Prometheus) | ||
중앙 로그 관리 (Logging) | 구조화된 로그 수집 및 검색 (예: ELK Stack) |
용어 정리
카테고리 | 용어 | 정의 및 설명 | 관련 아키텍처 |
---|---|---|---|
** 시스템 구성요소** | Message Broker | 생산자 - 소비자 간 메시지를 송수신하고 버퍼링, 라우팅, 전송 보장 처리 | MDA, EDA |
Event Bus | 이벤트 발행/구독 기반의 전파 중심 메시징 채널 (메시지 라우팅 포함) | EDA | |
Event Store | 발생한 모든 이벤트를 영속적으로 저장하는 저장소 | EDA | |
Dead Letter Queue (DLQ) | 처리 실패 메시지를 격리 보관하여 후속 처리나 모니터링에 활용하는 큐 | MDA, EDA | |
Projection | 이벤트 로그 (Event Stream) 를 읽기 모델로 변환하는 과정 | EDA | |
Correlation ID | 요청 - 응답/처리 흐름 추적을 위한 메시지 간 고유 식별자 | MDA, EDA | |
** 메시지/이벤트 단위** | Message | 명시적 명령 (Command), 요청 (Request), 응답 (Response), 데이터 전달을 포함한 단위 | MDA |
Event | 시스템에서 발생한 상태 변화나 사상 (Occurrence) 을 의미. 결과 지향적 | EDA | |
** 통신/설계 패턴** | Publish/Subscribe (Pub/Sub) | 발행자와 구독자 간 직접적 연결 없이 메시지를 중개 채널을 통해 전달하는 패턴 | MDA, EDA |
Saga Pattern | 분산 트랜잭션을 보상 트랜잭션 (Compensation) 으로 관리하는 패턴 | MDA, EDA | |
Compensating Transaction | 실패한 작업을 취소하거나 보정하는 트랜잭션 | MDA, EDA | |
Circuit Breaker | 장애 확산을 방지하고 빠른 실패 처리를 유도하는 안정성 제어 패턴 | MDA, EDA | |
Event Sourcing | 상태를 DB 에 저장하는 대신, 발생한 이벤트 시퀀스를 저장하고 이를 재생해 상태를 복원 | EDA | |
** 품질 및 운영 특성** | Idempotency (멱등성) | 동일 메시지를 여러 번 처리해도 결과가 동일하게 유지되는 속성 | MDA, EDA |
Eventual Consistency | 즉시 일관성은 보장하지 않지만 시간이 지나면 일관성을 확보하는 모델 | EDA | |
Back Pressure | 처리량 초과 시 시스템 안정성 유지를 위한 흐름 제어 기법 | MDA, EDA | |
Bulkhead | 장애 격리를 위한 시스템 분할 전략 (마이크로서비스의 독립 실행 보장) | MDA, EDA | |
Distributed Tracing | 다중 서비스 간 요청 흐름을 추적하기 위한 기법 (예: Jaeger, Zipkin) | MDA, EDA |
참고 및 출처
- Message-Driven vs Event-Driven Architecture 비교 - GeeksforGeeks
- Event vs Message: 차이와 실무 적용 - Medium (Simpplr Tech)
- Event-Driven vs Message-Driven 구조 비교 - Medium (Alex Dorand)
- Scaling Microservices: Message vs Event - Medium (Leela Kumili)
- Message vs Event Driven Architecture 비교 - LinkedIn (Saurabh Mishra)
- Message vs Event: 개념 차이와 적용 가이드 - Akka Guide
- Messaging vs Event-Driven Architecture 선택 가이드 - LinkedIn
- Microservices Pattern: Event-Driven Architecture - Microservices.io
- Asynchronous Message-Based Communication - Microsoft Learn
- Message-Driven Systems in Reactive Architecture - AWS Whitepaper
- Messaging Patterns for Event-Driven Microservices - Solace
- Event-Driven Architecture 개요 - Confluent
- Event-Driven Architecture 베스트 프랙티스 - AWS Architecture Blog
- Event-Driven Architecture 스타일 설명 - Azure Architecture Center
- CQRS 패턴 소개 - Azure Architecture Center
- CQRS & Event Sourcing with Java - Baeldung
- Amazon EventBridge 소개 - AWS 공식 문서
- Saga Pattern in Microservices - Microsoft Docs
- Idempotent Consumer 구현 - Apache Kafka Docs
- Distributed Tracing 개요 - OpenTelemetry
- Message Broker vs Event Broker - Dev.to
- Event-Driven vs Message-Driven Architecture - Baeldung
- RabbitMQ 공식 문서
- Apache Kafka 공식 문서
- Message Broker 아키텍처 스타일 - Microsoft Architecture Center