본문으로 이동
메뉴 여닫기
환경 설정 메뉴 여닫기
개인 메뉴 여닫기
로그인하지 않음
지금 편집한다면 당신의 IP 주소가 공개될 수 있습니다.
Event-Driven Architecture; EDA; 이벤트 드리븐 아키텍처
시스템 구성 요소가 서로 직접 호출하지 않고, 상태 변화(이벤트)를 발행하고 그 이벤트에 반응하는 방식으로 협력하는 소프트웨어 아키텍처 스타일

이벤트는 "장바구니에 상품이 담김", "파일이 업로드됨", "주문이 배송 준비됨"처럼 이미 일어난 상태 변화나 갱신을 뜻한다. 요청-응답 방식에서는 주문 서비스가 결제·재고·배송 서비스를 차례로 호출하고 응답을 기다리지만, 이벤트 기반 방식에서는 주문 서비스가 "주문 생성" 이벤트를 내보내기만 하고 관심 있는 서비스가 각자 반응한다. 생산자는 누가 이벤트를 쓰는지 모르고, 소비자는 이벤트가 어디서 왔는지 몰라도 된다. 이 느슨한 결합 덕분에 구성 요소를 따로 확장·배포·교체할 수 있어 마이크로서비스 아키텍처와 서버리스 애플리케이션의 기본 통신 방식으로 쓰인다.

이벤트 라우터가 서비스끼리 직접 묶지 않고 이벤트를 걸러 여러 대상으로 보낸다
구성 요소 역할 예
이벤트 생산자(producer) 상태가 바뀌면 이벤트를 만들어 라우터나 채널에 보냄 주문 서비스, S3 버킷, IoT 기기, SaaS 애플리케이션
이벤트 라우터·채널(router/broker) 이벤트를 받아 걸러 내고 관심 있는 소비자에게 전달. 생산자와 소비자 사이의 완충 역할 이벤트 버스, 토픽, 대기열, 스트림
이벤트 소비자(consumer) 관심 있는 이벤트를 받아 처리. 처리 결과로 새 이벤트를 낼 수도 있음 결제 함수, 재고 서비스, 분석 파이프라인

이벤트의 내용

편집 원본 편집

이벤트에 데이터를 얼마나 담을지는 설계 선택이다.

방식 이벤트 내용 장점 단점
이벤트 알림(event notification) 식별자 위주("주문 #8942 배송됨") 이벤트가 작고, 데이터 노출이 적음 소비자가 상세 정보를 얻으려면 생산자에게 다시 조회해야 해 결합과 부하가 생김
이벤트로 상태 전달(event-carried state transfer) 필요한 상태를 함께 담음(상품명, 가격, 수량, 주소) 소비자가 추가 조회 없이 처리. 생산자가 멈춰도 소비자는 동작 이벤트가 커지고, 스키마 변경 관리와 데이터 중복이 생김

AWS 설명도 이벤트가 상태를 담을 수도 있고 식별자만 담을 수도 있다고 구분한다. 메시지 크기 한도(예: 아마존 SNS 256KiB)를 넘는 데이터는 S3에 두고 참조만 이벤트에 싣는다.

요청-응답 방식과 비교

편집 원본 편집
구분 요청-응답(동기 호출) 이벤트 기반(비동기)
결합 호출자가 피호출자의 주소·API·가용성에 의존 생산자와 소비자가 라우터만 앎
장애 전파 하위 서비스 장애가 호출자 실패로 이어짐 소비자가 멈춰도 이벤트는 쌓였다가 복구 후 처리
확장 가장 느린 서비스에 전체 처리량이 묶임 단계별로 독립 확장, 대기열이 급증 부하 흡수
기능 추가 호출자 코드 수정 필요 새 소비자만 구독시키면 됨
응답 즉시 결과를 돌려받음 결과를 호출자에게 돌려주려면 별도 설계 필요
일관성 강한 일관성 구현이 쉬움 대개 결과적 일관성
장점 단점
구성 요소가 독립적으로 확장되고 독립적으로 실패함 네트워크를 거치므로 지연 시간이 변동함. 초저지연 요구(고빈도 매매 등)에는 맞지 않음
새 기능을 기존 서비스 수정 없이 소비자로 추가 결과적 일관성으로 전체 상태 파악과 ACID 요구 처리가 어려움
폴링이 사라져 유휴 자원과 비용이 줄어듦 중복 전달이 생길 수 있어 소비자를 멱등하게 만들어야 함
대기열·버스가 부하 급증을 흡수 여러 서비스에 걸친 디버깅과 추적이 어려움(분산 추적 필요)
라우터에서 접근 정책·감사·암호화를 한곳에 적용 호출자에게 처리 결과를 돌려주는 흐름이 복잡해짐

마크 리처즈(Mark Richards)는 이벤트 기반 아키텍처를 이벤트 흐름을 누가 제어하느냐에 따라 중재자 토폴로지와 브로커 토폴로지 두 가지로 나눈다.

중재자 토폴로지

편집 원본 편집
Mediator Topology
중앙의 이벤트 중재자가 하나의 업무 이벤트를 처리하는 데 필요한 단계와 순서를 알고, 각 단계를 이벤트 처리기에 지시하는 구조
구성 요소 역할
이벤트 큐(event queue) 클라이언트나 다른 시스템이 보낸 최초 이벤트(initial event)를 받아 중재자에게 전달
이벤트 중재자(event mediator) 최초 이벤트를 받아 처리 단계를 판단하고, 단계별 처리 이벤트(processing event)를 만들어 채널로 보냄. 단계 순서·병렬 여부·오류 처리를 관리(오케스트레이션). 업무 로직 자체는 수행하지 않음
이벤트 채널(event channel) 중재자가 보낸 처리 이벤트를 처리기에 전달하는 대기열·토픽
이벤트 처리기(event processor) 처리 이벤트를 받아 실제 업무 로직을 수행하는 독립 컴포넌트. 다른 처리기에 의존하지 않음

예를 들어 "주문 접수" 최초 이벤트가 오면 중재자가 "재고 확보 → 결제 → 배송 지시 → 고객 알림" 순서로 처리 이벤트를 하나씩 보내고, 결제가 실패하면 재고 확보를 취소하는 보상 단계까지 지시한다. 단순한 흐름은 Apache Camel·Spring Integration 같은 통합 프레임워크로, 사람 승인이나 장기 실행이 섞인 복잡한 흐름은 BPM 엔진이나 AWS Step Functions 같은 워크플로 엔진으로 구현한다.

브로커 토폴로지

편집 원본 편집
Broker Topology
중앙 제어자 없이 메시지 브로커만 두고, 각 이벤트 처리기가 이벤트를 받아 자기 일을 한 뒤 그 결과를 새 이벤트로 발행해 다음 처리기가 이어받는 연쇄 구조
구성 요소 역할
브로커(broker) 이벤트 채널(토픽·대기열)을 제공하는 경량 메시지 전달자. 흐름을 판단하지 않고 전달만 함
이벤트 처리기(event processor) 시작 이벤트(initiating event)나 다른 처리기의 이벤트를 구독해 처리하고, "무엇을 했는지"를 새 처리 이벤트로 발행

"주문 접수" 이벤트를 재고 서비스가 받아 재고를 확보하고 "재고 확보됨"을 발행하면, 결제 서비스가 그것을 받아 결제하고 "결제 완료"를 발행하는 식으로 흐름이 이어진다(코레오그래피). 전체 흐름은 어느 한 곳에도 적혀 있지 않고 처리기들의 구독 관계로만 존재한다. 아파치 카프카, RabbitMQ, ActiveMQ, 아마존 SNS가 브로커로 쓰인다.

구분 중재자 토폴로지 브로커 토폴로지
흐름 제어 중앙 중재자가 오케스트레이션 처리기끼리 이벤트 연쇄(코레오그래피)
구성 요소 이벤트 큐, 이벤트 중재자, 이벤트 채널, 이벤트 처리기 브로커(이벤트 채널), 이벤트 처리기
이벤트 종류 최초 이벤트 → 중재자가 만든 처리 이벤트 시작 이벤트 → 처리기가 발행한 처리 이벤트
결합도 처리기가 중재자에 묶임 처리기 간 결합이 매우 낮음
성능·확장성 중재자가 병목이 될 수 있음 병렬성이 높고 확장이 쉬움
장애 영향 중재자가 단일 장애점이 될 수 있음(이중화 필요) 중앙 요소가 없어 내결함성이 높음
오류 처리·복구 중재자가 진행 상태를 알아 재시도·보상·재시작이 쉬움 전체 상태를 아는 곳이 없어 오류 처리와 일관성 확보가 어려움
흐름 가시성 중재자 정의에서 전체 흐름이 보임 흐름이 흩어져 있어 파악·디버깅이 어려움(분산 추적 필요)
기능 추가 중재자 흐름 정의를 고쳐야 함 새 처리기가 구독만 하면 됨
적합한 경우 단계가 많고 순서·조건·보상이 중요한 업무(주문 처리, 보험 청구) 단순한 흐름, 높은 처리량, 독립적으로 늘어나는 후속 처리(알림, 분석)

실무에서는 둘을 섞는다. 핵심 업무 흐름은 중재자로 통제하고, 그 결과로 나온 이벤트에 알림·분석 같은 부가 처리는 브로커 방식으로 붙인다.

  • 팬아웃: 이벤트 하나를 여러 소비자가 병렬로 처리한다. 발행-구독 모델이 기본이다.
  • 버퍼링·부하 평탄화: 빠른 생산자와 느린 소비자 사이에 대기열을 둔다. 주문 접수는 빠르게 받고 결제 처리는 일정한 속도로 꺼내 간다.
  • 코레오그래피와 오케스트레이션: 각 서비스가 이벤트에 반응해 다음 이벤트를 내는 방식(코레오그래피)은 결합이 낮지만 흐름이 잘 안 보인다. 순서·재시도·보상이 중요한 업무 흐름은 중앙 오케스트레이터가 관리하는 편이 낫다.
  • 이벤트 아카이브·재생: 이벤트를 저장해 두었다가 장애 복구나 새 소비자 초기화에 다시 흘려보낸다.
  • 멱등 처리: 같은 이벤트가 두 번 와도 결과가 같도록, 이미 처리한 이벤트 ID를 기록하거나 상태를 확인한 뒤 처리한다.
역할 AWS 서비스 쓰임
이벤트 라우터(버스) 아마존 EventBridge AWS 서비스·SaaS·자체 앱 이벤트를 규칙으로 필터링해 대상에 전달
발행-구독 아마존 SNS 한 메시지를 많은 구독자에게 팬아웃
대기열 아마존 SQS 이벤트를 보관하고 소비자가 자기 속도로 처리, 실패 메시지는 DLQ로 격리
이벤트 스트림 아마존 Kinesis, 아마존 MSK(아파치 카프카) 순서 있는 대량 이벤트를 여러 소비자가 다시 읽기
소비자(컴퓨팅) AWS Lambda, AWS Fargate 이벤트마다 코드 실행
오케스트레이션 AWS Step Functions 여러 단계의 순서, 재시도, 사람 승인 관리

예를 들어 S3에 이미지가 올라오면 S3 이벤트가 EventBridge로 가고, 규칙이 썸네일 생성 Lambda와 메타데이터 저장 대기열에 동시에 이벤트를 보낸다. 썸네일 함수가 실패해도 메타데이터 처리는 영향을 받지 않는다.

  • "구성 요소를 분리", "한 구성 요소 장애가 다른 곳에 번지지 않게", "독립적으로 확장"이라는 요구는 이벤트 기반 설계(SQS, SNS, EventBridge)로 푼다.
  • 직접 동기 호출로 묶인 보기는 결합도가 높아 오답인 경우가 많다.
  • 이벤트가 중복 전달될 수 있으므로 소비자는 멱등하게 만든다는 점을 기억한다.
  • 응답이 즉시 필요한 대화형 요청이나 강한 일관성이 필수인 처리에는 동기 방식이 여전히 맞다.
  • 여러 단계 흐름의 순서와 보상이 중요하면 이벤트만으로 엮기보다 Step Functions 오케스트레이션을 고른다.
  • 중재자 토폴로지는 중앙 중재자가 흐름을 통제(오케스트레이션)하고, 브로커 토폴로지는 처리기들이 이벤트를 이어 발행(코레오그래피)한다. 오류 처리·복구는 중재자가, 확장성·결합도는 브로커가 유리하다.