Skip to main content

Kafka 기반 이벤트 소싱 MSA 구성

Turaco 아키텍처 디자이너에서는 Kafka 컴포넌트를 이용하여 서비스 간 요청을 동기 호출로만 연결하지 않고, 이벤트를 발행하고 구독하는 방식의 MSA를 설계할 수 있습니다.

이벤트 소싱과 Kafka

이벤트 소싱은 서비스의 상태 변화를 이벤트로 기록하고, 이벤트를 재생하거나 구독하여 현재 상태를 구성하는 설계 방식입니다. Kafka는 이벤트를 순서 있게 전달하고 보관하는 이벤트 로그 역할을 수행할 수 있으며, 각 서비스는 필요한 이벤트를 구독하여 자신의 저장소나 조회 모델을 갱신합니다.

적용 시나리오

Kafka 기반 이벤트 소싱 구조는 서비스 간 결합도를 낮추고, 장애가 발생해도 이벤트를 다시 처리할 수 있는 구조가 필요할 때 사용합니다.

예를 들어 주문 도메인은 아래와 같은 흐름으로 구성할 수 있습니다.

사용자 요청
-> Order Service
-> order-created 이벤트 발행
-> Payment Service, Inventory Service 이벤트 구독
-> payment-completed, inventory-reserved 이벤트 발행
-> Order Service 주문 상태 갱신

이 구조에서는 각 서비스가 자신의 데이터베이스를 독립적으로 관리하고, 다른 서비스의 내부 테이블에 직접 접근하지 않습니다. 서비스 간 상태 변경은 Kafka 토픽에 기록된 이벤트를 통해 전달합니다.

아키텍처 설계

아키텍처 설계 화면에서 다음 컴포넌트를 배치합니다.

구분컴포넌트역할
네트워크Ingress 또는 Istio외부 요청을 프론트엔드 또는 API 서비스로 전달
프론트엔드React, Vue, Angular사용자 화면 구성
백엔드Springboot, Node.js, FastAPI이벤트를 발행하거나 구독하는 마이크로서비스
메시징Kafka서비스 간 이벤트 전달 및 이벤트 로그 구성
데이터베이스MariaDB, MySQL, PostgreSQL, Redis, MongoDB서비스별 상태 저장 또는 조회 모델 저장

Kafka 컴포넌트 배치

서비스 연결

  1. Kafka 컴포넌트를 메시징 카테고리에서 디자이너 화면으로 배치합니다.
  2. 이벤트를 발행할 백엔드 서비스를 Kafka와 연결합니다.
  3. 이벤트를 구독할 백엔드 서비스도 Kafka와 연결합니다.
  4. 각 백엔드 서비스는 자신의 데이터베이스와 연결합니다.
  5. 프론트엔드는 외부 요청을 처리할 백엔드 서비스와 연결합니다.

Kafka를 중심으로 연결하더라도 모든 서비스가 같은 데이터베이스를 공유하지 않도록 설계합니다. 이벤트 소싱 또는 이벤트 기반 MSA에서는 서비스별 데이터 소유권을 분리하는 것이 중요합니다.

Kafka 속성 설정

Kafka 컴포넌트에서는 토픽, 복제 노드 수, 포트, 스토리지, 서비스 역할을 설정합니다.

토픽 설계

이벤트는 도메인 행위가 드러나는 이름으로 토픽을 구성합니다.

토픽 예시설명
order-events주문 생성, 주문 취소, 주문 상태 변경 이벤트
payment-events결제 요청, 결제 완료, 결제 실패 이벤트
inventory-events재고 예약, 재고 차감, 재고 부족 이벤트

토픽을 너무 세분화하면 운영 복잡도가 증가하고, 너무 넓게 잡으면 소비자가 불필요한 이벤트까지 처리해야 합니다. 서비스 경계와 이벤트 조회 패턴을 기준으로 토픽을 나눕니다.

서비스 및 역할

Kafka 컴포넌트의 서비스 및 역할 설정에서 Kafka를 사용할 백엔드 서비스를 선택하고 역할을 지정합니다.

Kafka 서비스 및 역할 설정

역할은 아래 기준으로 지정합니다.

역할사용 기준
Publisher서비스에서 도메인 이벤트를 발행할 때 선택
Subscriber서비스에서 다른 도메인의 이벤트를 구독할 때 선택

하나의 서비스가 이벤트를 발행하면서 동시에 다른 이벤트를 구독해야 하는 경우 Publisher와 Subscriber를 모두 선택할 수 있습니다.

이벤트 모델 작성 기준

이벤트는 나중에 다시 처리되거나 다른 서비스에서 해석될 수 있으므로, 명확하고 안정적인 스키마로 작성합니다.

{
"eventId": "evt-20260513-0001",
"eventType": "OrderCreated",
"eventVersion": 1,
"aggregateId": "order-10001",
"occurredAt": "2026-05-13T10:30:00+09:00",
"payload": {
"orderId": "order-10001",
"userId": "user-001",
"items": [
{
"sku": "SKU-001",
"quantity": 2
}
]
}
}

이벤트에는 eventId, eventType, eventVersion, aggregateId, occurredAt처럼 추적과 재처리에 필요한 값을 포함하는 것을 권장합니다.

구현 시 주의 사항

멱등성

Kafka 메시지는 장애 복구나 재시도 과정에서 중복 처리될 수 있습니다. Consumer 서비스는 eventId 또는 비즈니스 키를 기준으로 이미 처리한 이벤트인지 확인해야 합니다.

이벤트 버전

서비스가 독립적으로 배포되면 이벤트 구조도 변경될 수 있습니다. 이벤트에 eventVersion을 포함하고, Consumer는 구버전 이벤트를 처리할 수 있는 호환 로직을 유지합니다.

실패 처리

Consumer 처리 중 오류가 발생하면 같은 메시지를 무한히 재시도하지 않도록 재시도 횟수와 실패 이벤트 처리 정책을 정합니다. 운영 환경에서는 실패 이벤트를 별도 토픽이나 로그로 분리하여 후속 조치를 할 수 있게 구성합니다.

트랜잭션 경계

서비스의 데이터베이스 저장과 Kafka 이벤트 발행이 함께 필요한 경우, 저장은 성공했지만 이벤트 발행이 실패하는 상황을 고려해야 합니다. 이런 경우 Outbox Pattern을 적용하여 DB에 이벤트 발행 대상을 먼저 기록하고, 별도 프로세스가 Kafka로 발행하는 구조를 사용할 수 있습니다.

애플리케이션 생성 및 배포

아키텍처 설계가 완료되면 애플리케이션을 생성하고 스테이지에 배포합니다.

아키텍처 배포

아키텍처 배포에 필요한 설정 가이드는 각 페이지를 참고해주세요.

배포 순서

Kafka를 사용하는 백엔드 서비스는 Kafka 접속 정보가 필요합니다. 스테이지 리소스 배포 시 Kafka와 각 서비스가 사용하는 데이터베이스를 먼저 배포한 후, 백엔드 서비스를 배포하는 것을 권장합니다.

운영 확인

배포 후에는 아래 항목을 확인합니다.

확인 항목확인 내용
Kafka Pod 상태Kafka 브로커와 관련 리소스가 정상 실행 중인지 확인
Topic 생성 여부설계한 토픽이 생성되었는지 확인
Producer 로그이벤트 발행 성공 또는 실패 로그 확인
Consumer 로그이벤트 수신, 처리, 재시도 로그 확인
서비스별 DBConsumer가 이벤트를 처리한 결과가 각 서비스 저장소에 반영되었는지 확인

Kafka 기반 MSA는 서비스 간 직접 호출을 줄이는 대신, 이벤트 흐름과 실패 처리 정책이 중요해집니다. 아키텍처 설계 단계에서 토픽, 이벤트 이름, 서비스 역할, 재처리 기준을 함께 정의하면 운영 단계의 추적과 장애 대응이 쉬워집니다.