우아한테크코스 테코톡
강산의 이벤트 기반 아키텍처
https://youtu.be/wUudBNlWNLM?si=D5RnGC6z3sGVUwrP
강산의 이벤트 기반 아키텍처
- 강산의 이벤트 기반 아키텍처
이벤트 기반 아키텍처(EDA): 왜 쓰는가에 대한 본질적인 답
이벤트 기반 아키텍처(Event-Driven Architecture, EDA)는 종종 “비동기 처리”, “Kafka 쓰는 아키텍처” 정도로 이해되지만, 핵심은 전혀 다른 곳에 있다.
결론부터 말하면 EDA의 본질은 이것이다.
“결합도를 낮추기 위한 구조적 선택”
발표에서도 여러 기업과 아키텍처 권위자들의 공통된 메시지를 정리하면 결국 하나로 귀결된다.
- Microsoft → decoupled (분리)
- AWS / Google → loose coupling (느슨한 결합)
- Martin Fowler → decouple + loose coupling
👉 즉, 이벤트를 쓰는 이유는 단 하나다. 결합도를 낮추기 위해서다.
기존 구조의 문제: 직접 호출 기반 시스템
일반적인 서비스 구조는 이런 형태다.
Order Service → Payment Service
→ Shipping Service
→ Notification Service
이 구조의 문제는 생각보다 크다.
1. 강한 의존성
- 주문 서비스가 결제/배송/알림을 모두 알아야 한다
2. 연쇄 실패
- 결제 실패 → 주문 실패
- 배송 지연 → 전체 지연
3. 변경 전파
- 배송 정책 변경 → 주문 코드 수정 필요
👉 핵심 문제
“하나의 흐름에 모든 서비스가 묶여 있다”
EDA로 바꾸면 무엇이 달라질까
EDA에서는 구조가 이렇게 바뀐다.
Order Service → Event Broker → (Payment / Shipping / Notification)
주문 서비스는 더 이상 직접 호출하지 않는다.
대신 이벤트를 발행한다.
OrderCompleted Event
그리고 나머지 서비스는 이 이벤트를 구독해서 처리한다.
결합도는 실제로 어떻게 줄어들까
EDA의 핵심은 “결합이 줄어든다”인데, 여기서 중요한 건 결합의 종류다.
1. 물리적 결합 감소
- 기존: 특정 서비스 직접 호출
- 변경: 브로커에게 이벤트 발행
👉 서비스 간 직접 연결이 사라진다
2. 시간적 결합 감소
- 기존: 호출 → 응답 기다림
- 변경: 이벤트 발행 후 바로 종료
👉 소비자는 언제 처리해도 된다
👉 지연/실패가 전파되지 않는다
3. (중요) 개념적 결합은 남는다
여기서 많은 사람들이 착각한다.
이벤트를 쓰면 모든 결합이 사라진다고 생각하지만, 사실은 아니다.
예를 들어 이런 메시지를 보자.
ProcessPayment
DispatchShipment
SendNotification
이건 이벤트가 아니다.
👉 “명령(Command)”이다
왜냐하면:
- “무엇을 해라”라고 지시하고 있기 때문
이 경우 문제는 그대로 남는다.
- 발행자가 소비자의 정책을 알고 있음
- 정책 바뀌면 발행자도 수정해야 함
👉 개념적 결합이 유지된다
Command vs Event (핵심 구분)
이 부분이 EDA에서 가장 중요하다.
Command (명령)
StartShipment
ProcessPayment
- 미래 지향
- “누가 무엇을 해라”
- 강한 결합 발생
Event (이벤트)
OrderCompleted
PaymentSucceeded
ShipmentStarted
- 과거 지향
- “무슨 일이 발생했다”
- 결합 없음
👉 핵심 문장
“이벤트는 사실을 말하고, 커맨드는 행동을 지시한다”
올바른 이벤트 설계
좋은 이벤트는 이렇게 생긴다.
OrderCompleted
그리고 각 서비스는 이렇게 반응한다.
- 결제 서비스 → 결제 처리
- 배송 서비스 → 배송 준비
- 알림 서비스 → 알림 발송
👉 중요한 점
발행자는 아무것도 지시하지 않는다
👉 소비자가 알아서 행동한다
이게 진짜 느슨한 결합이다.
느슨한 결합이 가져오는 진짜 효과
EDA의 효과는 단순히 “비동기”가 아니다.
1. 변경 영향 최소화
- 결제 로직 변경 → 주문 영향 없음
2. 경계 안정성 확보
- 이벤트 스키마 = 시스템 경계
👉 계약 기반 설계 가능
3. 응집도 증가
- 각 서비스는 자기 역할만 수행
👉 SRP (단일 책임 원칙) 강화
4. 확장성 증가
- 새로운 서비스 추가 가능
👉 기존 코드 수정 없이 확장 (OCP 기반)
하지만 EDA는 만능이 아니다
EDA의 단점은 명확하다.
1. 흐름이 보이지 않는다
- 기존: 코드 한 줄로 흐름 파악
- EDA: 이벤트 체인으로 분산됨
👉 디버깅 난이도 상승
2. 운영 난이도 증가
- 이벤트 추적 필요
- 모니터링 필수
3. 문서 의존성 증가
- 흐름이 코드에 없음
- 문서 없으면 이해 불가
👉 실제로 “시스템은 돌아가는데 이해 못하는 상황” 발생
핵심 정리 (가장 중요한 3줄)
EDA의 본질은 기술이 아니다.
👉 구조다.
정리하면:
- 이벤트를 쓰는 이유 → 결합도 감소
- 메시징만으로는 부족 → 이벤트 설계가 핵심
- Command → 결합 유지 / Event → 결합 제거
그리고 가장 중요한 한 줄:
“EDA는 비동기가 아니라, 의존성을 끊는 아키텍처다.”
실무에서 반드시 기억해야 할 포인트
1. 이벤트는 “사실”만 담아라
→ OrderCompleted (O) → ProcessPayment (X)
2. 소비자의 정책을 몰라야 한다
→ 발행자는 독립적이어야 한다
3. 이벤트 스키마 = 계약이다
→ 버전 관리 필수
4. 모니터링 없으면 망한다
→ tracing / logging 필수
마무리
EDA는 단순히 Kafka를 붙이는 기술이 아니다. 그리고 “비동기 처리”를 위한 도구도 아니다.
EDA는 시스템을 이렇게 바꾸는 선택이다.
- 동기 호출 → 이벤트 기반 흐름
- 강한 결합 → 느슨한 결합
- 지시형 설계 → 반응형 설계
그리고 결국 이 한 문장으로 정리된다.
“EDA는 서비스를 서로 모르게 만드는 기술이다.”