이벤트 드리븐 아키텍처(Event-Driven Architecture, EDA)는 시스템에서 발생하는 이벤트(상태 변화나 행동)를 기반으로 동작하는 소프트웨어 설계 스타일입니다. 이는 비동기적으로 이벤트를 처리하며, 대규모 시스템에서 대용량 트래픽을 효과적으로 처리하고 서비스 간의 느슨한 결합을 통해 독립적으로 동작할 수 있도록 합니다.
이 글에서는 이벤트 드리븐 아키텍처의 주요 개념, 장점과 단점, 그리고 이를 실제로 구현할 때 사용하는 RabbitMQ와 Kafka에 대해 다룹니다.
전통적인 요청-응답 모델의 한계
- 동기적 통신:
- 전통적인 아키텍처는 주로 HTTP와 같은 동기적 요청-응답 모델을 사용한다.
- 클라이언트가 요청을 보내면 서버는 요청을 처리한 후 응답을 반환한다. 이 방식은 클라이언트가 응답을 기다리는 동안 블로킹(blocking) 상태가 되어 시스템의 응답성이 저하된다.
- 병목 현상:
- 서버가 많은 요청을 동시에 처리해야 하는 경우, 특정 서비스나 자원이 병목이 되어 전체 시스템의 성능이 저하될 수 있다.
- 확장성의 한계:
- 전통적인 모놀리식 아키텍처는 서비스의 일부만 확장할 수 없다. 전체 시스템을 확장해야 하므로 비용과 복잡도가 증가한다.
이벤트 드리븐 아키텍처 (Event-Driven Architecture, EDA)
이벤트 드리븐 아키텍처는 시스템에서 발생하는 이벤트를 중심으로 설계된 소프트웨어 아키텍처이다. 이벤트는 시스템 내에서 상태 변화나 특정 행동을 나타내는 메시지이다. 이 아키텍처는 비동기적으로 이벤트를 처리하며, 서비스 간의 느슨한 결합을 통해 각 서비스가 독립적으로 동작할 수 있도록 한다. 이를 통해 시스템의 유연성과 확장성을 높일 수 있다.
주요 개념
이벤트(Event)
이벤트는 시스템 내에서 발생하는 상태 변화나 행동을 나타내는 메시지이다. 예를 들어, 사용자가 쇼핑몰에서 제품을 구매하면 '주문 생성'이라는 이벤트가 발생할 수 있다.
이벤트 소스(Event Source)
이벤트 소스는 이벤트를 생성하여 이벤트 버스에 전달하는 역할을 합니다. 이는 주로 비즈니스 로직을 수행하는 서비스로, 특정 조건이나 사용자의 행동에 따라 이벤트를 생성한다.
이벤트 핸들러(Event Handler)
이벤트 핸들러는 이벤트를 수신하여 처리하는 역할을 한다. 이벤트가 발생하면 이를 구독(subscribe)한 핸들러가 해당 이벤트를 수신하여 비즈니스 로직을 실행한다.
이벤트 버스(Event Bus)
이벤트 버스는 이벤트 소스와 이벤트 핸들러 간의 메시지 전달을 중개합니다. Kafka, RabbitMQ와 같은 메시지 브로커가 대표적인 이벤트 버스이다.
이벤트 드리븐 아키텍처의 장점
- 비동기적 처리:
- 이벤트 드리븐 아키텍처는 비동기적 메시지 전달을 통해 서비스 간 통신을 처리한다. 이벤트가 발생하면 이를 비동기적으로 처리하여 클라이언트가 즉시 응답을 받을 수 있다.
- 이 방식은 시스템의 응답성을 향상시키고, 대량의 요청을 효율적으로 처리할 수 있게 한다.
- 느슨한 결합:
- 서비스 간 결합도를 낮춰 각 서비스가 독립적으로 동작할 수 있다. 이는 서비스별로 독립적인 확장과 배포가 가능하다는 것을 의미한다.
- 서비스가 서로 독립적으로 운영되기 때문에 특정 서비스의 장애가 전체 시스템에 미치는 영향을 최소화할 수 있다.
- 확장성과 유연성:
- 이벤트 드리븐 아키텍처는 수평 확장이 용이하다. 각 서비스가 독립적으로 확장할 수 있어 대규모 트래픽을 효과적으로 처리할 수 있다.
- 필요에 따라 이벤트 프로듀서와 컨슈머를 추가하여 시스템의 처리 능력을 향상할 수 있다.
- 실시간 데이터 처리:
- EDA는 실시간 데이터 스트리밍과 분석에 적합하다. 이벤트가 발생하는 즉시 처리하고, 이를 기반으로 실시간 피드백이나 응답을 제공할 수 있다.
- 로그 수집, 사용자 행동 분석, 모니터링 등 실시간 데이터 요구가 높은 분야에서 유용하다.
이벤트 드리븐 아키텍처의 단점
- 복잡성 증가
- 이벤트 기반 통신으로 인해 시스템의 복잡성이 증가할 수 있다. 이벤트 흐름과 상태 관리를 체계적으로 설계해야 하며, 각 서비스 간의 이벤트 상호작용을 잘 이해하고 관리할 필요가 있다.
- 장애 전파
- 이벤트 실패 시 다른 서비스로 장애가 전파될 수 있다. 이를 방지하기 위해 이벤트 재처리 및 장애 복구 메커니즘을 구현해야 한다. 이벤트 소스에서 이벤트를 생성하는 로직과 이벤트 핸들러에서 이를 처리하는 로직이 명확하게 설계되어야 한다.
RabbitMQ와 Kafka의 사용
이벤트 드리븐 아키텍처에서는 메시지 브로커를 사용하여 이벤트를 전달한다. RabbitMQ와 Kafka는 대표적인 메시지 브로커이다.
RabbitMQ
- 특징: 메시지 지향 미들웨어로, AMQP(Advanced Message Queuing Protocol)를 기반으로 한다. 메시지 전달의 신뢰성과 유연성이 뛰어나며, 복잡한 라우팅이 가능하다.
- 사용 사례: 단순한 작업 큐, 빠른 응답이 필요한 시스템에서 주로 사용된다.
- 장점: 메시지의 신뢰성이 높고, 다양한 메시지 라우팅 기능을 제공하여 유연하게 시스템을 설계할 수 있다.
Kafka
- 특징: 대용량 데이터 스트리밍 플랫폼으로, Pub/Sub 모델을 기반으로 한다. 높은 처리량과 내구성을 제공하며, 대규모 데이터 스트리밍에 최적화되어 있다.
- 사용 사례: 실시간 데이터 분석, 로그 수집, 이벤트 소싱 등 대규모 데이터 처리 및 분석 시스템에서 주로 사용된다.
- 장점: 높은 처리량과 확장성을 제공하며, 파티션을 통한 수평 확장이 용이하. 데이터의 지속성 보장이 강력하여 이벤트 소싱과 같은 패턴에 적합하다.
이벤트 드리븐 아키텍처 설계 예시: 온라인 쇼핑몰
- 이벤트 소스, Producer: 사용자가 온라인 쇼핑몰에서 주문을 한다. 주문 서비스가 '주문 생성' 이벤트를 발생시킨다.
- 이벤트 버스: Kafka나 RabbitMQ와 같은 메시지 브로커가 '주문 생성' 이벤트를 전달한다.
- 이벤트 핸들러, Consumer:
- 재고 서비스: '주문 생성' 이벤트를 수신하여 재고를 확인하고 업데이트한다.
- 배송 서비스: '주문 생성' 이벤트를 수신하여 배송 준비를 시작한다.
- 결제 서비스: '주문 생성' 이벤트를 수신하여 결제 처리를 한다.
마치며
실제 많은 애플리케이션에서 대용량 트래픽을 처리하기 위해 이러한 이벤트 드리븐 아키텍처를 설계하고, 메시지 큐를 사용한다.
이를 구현할 때는 이벤트 흐름과 상태 관리를 체계적으로 설계하며, 특히 장애 전파를 막기 위해 에러를 처리하는 중요하다.
장애 전파를 막기 위해서 에러를 처리하는 별도의 애플리케이션을 구성하여, 에러가 발생하면 적절히 처리하도록 구현할 수 있다.
참고
- 팀 스파르타 MSA 강의 자료
'Development > Tip' 카테고리의 다른 글
공부하며 얻은 잡다한 지식들 (2024.09.13 update) (0) | 2024.08.06 |
---|---|
[Redis] Redis 기초 (0) | 2024.08.05 |
[Tip] 소프트웨어 버전 번호 별 의미 (0) | 2024.07.31 |
[Tip] Github README에 내가 작성한 블로그 최신 글 가져오기 (0) | 2024.03.10 |
[Tip] KPT(Keep, Problem, Try) 방식으로 프로젝트 회고하기 (0) | 2024.02.25 |