#Backend

고객의 취소할 권리를 보장하다

고객의 취소할 권리를 보장하다
01

Summary

“아직 출발도 안 했는데 왜 안 되죠?” 올리브영이 주문 취소 마감을 출고 직전까지 늦춘 비결

이벤트 파이프라인과 Redis 분산 락을 활용해 고객의 취소할 권리를 안전하게 복원한 여정

올리브영 주문·배송 도메인 팀이 상품이 센터를 떠나기 직전까지 고객이 앱에서 자유롭게 주문을 취소할 수 있도록 시스템을 개편한 과정을 소개합니다. 배송유형별로 가장 늦은 취소 시점을 도출하고, Kafka 실시간 이벤트 전송 및 Redis 분산 락 등의 분산 시스템 아키처를 동원해 안전한 취소 프로세스를 완성했습니다.

  • 01배송유형별(센터배송, 업체배송, 오늘드림) 물리적 한계점 분석을 통해 취소 골든타임을 실물 출고 직전으로 재정의
  • 02상태 기반의 복잡한 분기문들을 단일 타임스탬프 필드인 '취소 불가 일시'로 일원화하여 상태 제어의 유연성 확보
  • 03Kafka 기반의 이벤트 스트리밍 방식을 채택하여 결합도를 낮추고, 누락 방지를 위한 이중 잠금 장치(출고 확정 이벤트 처리) 적용
  • 04오늘드림 배차와 주문 취소가 동시에 몰릴 때 발생하는 순서 엇갈림 문제를 Redis 분산 락 및 보상 트랜잭션 구조로 제어
  • 05파편화된 외부 배달대행사 API 스펙을 공통 어댑터 패턴으로 감싸 시스템 안정성과 확장성을 극대화

RECOMMENDATION

분산 환경에서의 동시성 문제 해결이 고민이거나, 실시간 물류·커머스 비즈니스 도메인에서 가역적 상태 관리를 안전하게 구현하고 싶은 백엔드 개발자에게 적극 추천합니다.

The Problem

올리브영 온라인몰은 기존에 물류의 출하 지시 시점을 기준으로 주문 취소를 차단하여, 실제 출고까지 시간이 남았음에도 고객이 앱에서 직접 취소하지 못하고 고객센터를 거쳐야 하는 불편함이 있었습니다.

The Solution

배송유형별 취소 마감 시점을 실물 출고 직전으로 늦추고, 취소 판단 로직을 '취소 불가 일시' 단일 필드로 통합했으며, Kafka 실시간 이벤트 스트리밍과 Redis 분산 락을 도입해 물류 연동 및 동시성 문제를 해결했습니다.

The Result

취소 판단 주체를 단순화하여 취소 상태 복원이 유연해졌으며, 외부 배달대행사 간 파편화된 인터페이스를 어댑터 패턴으로 공통화하고 배차와 취소 간 동시성 충돌과 실시간 이벤트 누락 사고를 차단했습니다.

Trade-off

취소 골든타임을 늦춘 만큼 실물 출고와 취소 완료 사이의 경계 케이스가 늘어나 물리적 출고 후 취소되는 금융 사고 위험이 커졌으며, 이를 막기 위해 이중 잠금(출고 확정 시점 처리) 및 수동 불일치 건 추적 시스템 등 더 촘촘한 예외 처리 로직을 구현해야 했습니다.

03

Key Concepts

Concept · 01

Redis 분산 락 (Distributed Lock)

분산 시스템 환경에서 공유 자원에 대한 동시 접근을 동기화하기 위해 공유 캐시 시스템인 Redis를 사용해 락을 제어하는 방식입니다.

  • 오늘드림 배송의 포장/배차 요청과 고객의 주문 취소가 동시에 진행되지 않도록 주문번호 단위로 락을 걸어 처리 과정을 완전히 격리했습니다.
  • 락 획득 후 데이터 최신화 처리를 동반하여, 외부 시스템 API 롤백이 불가능한 한계를 보상 트랜잭션 형태로 매끄럽게 유도했습니다.
Concept · 02

Kafka 이벤트 스트리밍 (Event Streaming)

중앙 집중형 로그 보관소이자 실시간 데이터 파이프라인 플랫폼으로, 결합도를 낮추며 시스템 간 데이터를 비동기로 전송할 때 사용됩니다.

  • 기존의 주기적 배치 방식 대신 물류 시스템의 실시간 '집품 완료' 이벤트를 발행하고 주문 시스템에서 이를 즉시 구독해 처리하도록 연동 방식을 개선했습니다.
Concept · 03

어댑터 디자인 패턴 (Adapter Design Pattern)

호합성이 없는 인터페이스들을 협업할 수 있도록 중간에서 규격을 변환해 연결하는 구조적 설계 패턴입니다.

  • 제휴 배달대행사별로 상이한 요청 형식, 취소 코드, 오류 코드 스펙을 표준 인터페이스로 추상화하여 공통 재시도 규칙을 구현하고 확장을 손쉽게 만들었습니다.