피드로 돌아가기
컬리 기술블로그Backend
원문 읽기
컬리의 입고 시스템이 외부 인입 데이터를 안전하게 동기화하는 방법
컬리가 아웃박스 패턴과 Kafka RetryableTopic을 결합해 외부 채널 입고 데이터 동기화 중 DB 쓰기와 메시지 발행의 원자성 보장 및 자동 재시도 메커니즘 구현
AI 요약
Context
컬리의 3PL 사업 확장으로 외부 파트너사로부터 다양한 형태의 입고 예정 정보가 수신되면서, 기존 레거시 시스템의 문제점이 노출되었다. 인터페이스 DB 테이블 저장과 Kafka 메시지 발행 사이의 원자성이 보장되지 않아, 네트워크 장애나 커밋 실패 시 데이터 불일치가 발생했다. 또한 컨슈머에서 필수 기반 정보(파트너 정보, 상품 정보 등) 미완성으로 인한 처리 실패 시 수동 개입이 필요했다.
Technical Solution
- 아웃박스 패턴 도입: 인터페이스 DB 저장 시 카프카 메시지를 직접 발행하는 대신 별도의 outbox_record 테이블에 메시지 페이로드를 기록하고, 별도 폴러(Poller)가 주기적으로 읽어와 메시지 발행 처리하도록 변경
- Namastack Outbox for Spring Boot 라이브러리 채택: 아웃박스 테이블 관리, 폴링 스케줄링, 재시도 횟수/상태 관리 등을 라이브러리에 위임하여 구현 복잡도 감소
- Kafka RetryableTopic 적용: 컨슈머에서 처리 실패 시 자동으로 재시도 토픽으로 메시지를 라우팅하고, 설정된 횟수만큼 재시도한 후 최종 실패 시 데드레터 토픽으로 전달
- 발행부와 수신부 책임 분리: 발행부는 아웃박스 패턴으로 메시지 안전 전송에 집중하고, 수신부는 RetryableTopic으로 자신의 재시도 상태를 독립적으로 관리
- 자동 알람 메커니즘: 재시도 토픽 처리가 최종 실패하여 데드레터 토픽에 도달한 메시지에 대해 @DltHandler를 통해 자동 알람 발송
Key Takeaway
외부 채널에서의 비동기 데이터 동기화 시 아웃박스 패턴과 이벤트 기반 재시도 메커니즘을 결합하면, 운영자 개입 없이 시스템 자체에서 자가 치유(self-healing)가 가능하다. 검증된 라이브러리를 활용하여 인프라 구현 복잡도를 줄이고 비즈니스 로직 고도화에 에너지를 투자하는 것이 중요하다.
실천 포인트
3PL, 마켓플레이스, 멀티테넌트 아키텍처에서 외부 파트너 데이터를 수신하는 시스템을 구축할 때, Namastack Outbox for Spring Boot와 같은 아웃박스 구현 라이브러리를 도입하고 Kafka RetryableTopic으로 컨슈머 재시도를 자동화하면, 프로듀서-컨슈머 간 데이터 불일치를 제거하고 수동 모니터링 비용을 대폭 감소시킬 수 있다.