
아웃박스 패턴과 재시도 토픽으로 완성한 3PL 물류 시스템의 강력한 데이터 정합성 아키텍처
컬리가 직매입 모델(1P)에서 3자 물류(3PL)로 사업을 확장하며 직면한 외부 데이터 동기화 문제를 해결한 기술적 여정을 다룹니다. DB 트랜잭션과 메시징 시스템 사이의 간극을 메우는 아웃박스 패턴과 복잡한 재시도 메커니즘을 프레임워크의 표준 기능을 활용해 우아하게 구현한 사례를 소개합니다.
마이크로서비스 아키텍처(MSA)에서 서비스 간 데이터 정합성이 중요하거나, 외부 연동 시 발생하는 일시적 오류를 자동화된 재시도로 해결하고 싶은 백엔드 개발자들에게 실무적인 가이드를 제공합니다.
3PL 사업 확장으로 외부 채널의 다양한 데이터 인입이 증가함에 따라, DB 쓰기와 메시지 발행 간의 원자성 미보장으로 인한 데이터 불일치 이슈와 참조 데이터 미생성으로 인한 일시적 처리 실패 시 운영자의 수동 개입이 빈번해지는 문제가 발생했습니다.
DB와 메시지 발행의 원자성을 보장하기 위해 'Namastack Outbox' 라이브러리를 활용한 아웃박스 패턴을 도입하고, 일시적인 오류에 대응하기 위해 Spring Kafka의 @RetryableTopic을 적용하여 최대 24시간 동안 10분 간격으로 자동 재시도가 가능하도록 시스템을 보완했습니다.
인터페이스 테이블과 메시지 큐 간의 원자적 일관성을 확보하였으며, 시스템 스스로 일시적 오류를 복구하는 자가 치유(Self-healing) 구조를 달성하여 야간 등 비가동 시간대에도 운영자 개입 없이 안정적인 데이터 동기화가 가능해졌습니다.
Trade-off
카프카 메시지 발행 성공 후 아웃박스 상태 마킹 과정에서 장애가 발생할 경우 동일 메시지가 중복 발행될 가능성이 존재하므로, 이를 처리하는 컨슈머 측의 멱등성 보장 설계가 필수적으로 요구됩니다.
데이터베이스 트랜잭션과 메시지 브로커 전송을 하나의 원자적 작업으로 묶기 위해, 발행할 이벤트를 DB의 전용 테이블에 먼저 기록하는 아키텍처 패턴입니다.
메시지 컨슘 중 예외 발생 시 메인 토픽을 블로킹하지 않고 별도의 재시도 토픽으로 메시지를 넘겨 지연 처리하는 Spring Kafka의 기능입니다.
재시도 간격이 동일한 경우 여러 개의 재시도 토픽을 생성하지 않고 단일 토픽을 재사용하여 카프카 클러스터의 부하를 줄이는 전략입니다.




