피드로 돌아가기
강남언니 공식 블로그Backend
원문 읽기
분산 시스템에서 메시지 안전하게 다루기
강남언니 광고 시스템이 Transactional Outbox Pattern을 도입해 분산 시스템에서 메시지 발행-데이터 일관성 문제 해결
AI 요약
Context
분산 시스템에서 여러 독립적인 데이터베이스를 가진 서비스들 간 메시징 방식 통신 시 메시지 발행과 데이터 커밋의 순서 보장 실패로 인해 발행되지 않아야 할 메시지가 발행되거나, 발행되어야 할 메시지가 누락되는 데이터 일관성 문제가 발생했다. 특히 마켓 시스템의 트랜잭션 커밋 지연 중 검색 시스템이 미발행 이벤트 메시지를 수신하여 아직 존재하지 않는 상품을 조회하거나, 메시지 발행 순서가 뒤바뀌어 상품 상태 토글링 시 검색 인덱스의 상태가 일치하지 않는 현상이 발생했다.
Technical Solution
- 도메인 이벤트를 Campaign 애그리거트 내 List 타입 Collection에 저장: 명령 실행 결과 발생한 복수의 도메인 이벤트를 발생 순서대로 기록
- 이벤트 저장소를 Outbox 역할로 전환: CampaignRepository의 update() 메서드에서 @Transactional 트랜잭션 내에 도메인 이벤트 목록을 함께 영속화하여 데이터 변경과 이벤트 기록을 원자성으로 보장
- 주기적 이벤트 발행기 도입: 미발행 상태의 도메인 이벤트를 정기적으로 조회해 메시지 브로커로 발행한 후 발행 완료 표시 수행
- 메시지 발행 순서 보장: EventStore에 저장된 이벤트를 저장 순서대로 발행하여 ON→OFF→ON 토글 시 메시지 순서 유지
- 배치 보상 프로세스 불필요: 메시지 발행의 원자성이 보장되므로 별도 복구 로직 없이 결과적 일관성 달성
Key Takeaway
분산 시스템에서 메시지 기반 이벤트 통신 시 트랜잭션 커밋과 메시지 발행을 별도로 처리하면 안 되며, Transactional Outbox Pattern을 통해 데이터 변경과 이벤트 저장을 단일 트랜잭션으로 묶음으로써 메시지 손실과 순서 역전을 근본적으로 차단할 수 있다.
실천 포인트
도메인 주도 설계(DDD)를 적용하는 다중 데이터베이스 마이크로서비스 환경에서 이벤트 발행 안정성이 필요할 때, 애그리거트 내부에 발생한 도메인 이벤트를 List 타입으로 수집한 후 Repository의 단일 @Transactional 메서드에서 비즈니스 데이터와 이벤트 저장소 레코드를 함께 커밋하고, 별도의 배치 프로세스가 미발행 이벤트를 발행 상태로 갱신하는 방식을 적용하면 메시지 누락 및 순서 보장 문제를 해결할 수 있다.