글로벌 로그인 이후에도 과거 주문 조회를 유지하는 구조
컷오버 이후 사용자는 글로벌 Nike 계정으로 로그인한다. 이 상태에서 사용자가 ‘내 주문 내역’을 조회하면, 글로벌 플랫폼의 주문과 Breeze 시절의 주문이 모두 보여야 한다. 이 글은 두 개의 서로 다른 데이터 소스(글로벌 주문 시스템 + BLOHA)에서 데이터를 가져와 통합하여 사용자에게 보여주는 구조를 기록한다.
이 구조의 핵심 도전은 두 시스템의 주문 데이터 스키마가 다르다는 점이다. 글로벌 주문 데이터와 Breeze 주문 데이터의 필드, 상태 코드, 날짜 형식이 모두 다르다. 사용자에게는 이 차이가 보이지 않아야 한다 — ‘예전 주문이랑 요즘 주문이 같은 형태로 보여야’ 한다.
글로벌 플랫폼 전환 후 주문 조회 흐름은 아래 단계로 동작했다.
용어 정리:
글로벌 계정 연결 키: 로컬 계정과 글로벌 계정을 연결하기 위한 공통 식별자BLOHA: Breeze 시절 주문 이력을 조회하기 위한 레거시 브리지 API
참고:
글로벌 계정 연결 키매핑 정확도는 과거 주문 노출 정확도와 직접 연결된다.
글로벌 로그인
사용자가 글로벌 Nike 계정으로 로그인한다.
주문 조회 요청
사용자가 주문 내역 조회를 요청한다.
글로벌 주문 조회
주문 서비스가 글로벌 주문 시스템에서 현재 주문을 조회한다.
과거 주문 조회
같은 요청에서 글로벌 계정 연결 키 기준으로 BLOHA에서 Breeze 과거 주문을 조회한다.
응답 스키마 매핑
두 결과를 같은 응답 스키마로 매핑한다.
병합 응답 반환
병합 목록을 날짜 역순으로 정렬해 사용자에게 반환한다.
이 병합 과정에서 가장 어려운 부분은 스키마 통합이다. 글로벌 주문의 상태는 ‘DELIVERED’, ‘RETURNED’ 같은 영어 코드를 사용하고, Breeze의 상태는 다른 코드 체계를 사용한다. 금액 표시도 글로벌은 소수점을 포함하지만 한국 원화는 정수다. 이런 차이들을 통합 뷰에서 일관되게 표현해야 한다.
병합 규칙 요약 표
| 항목 | 글로벌 주문 | Breeze 과거 주문(BLOHA) | 통합 규칙 |
|---|---|---|---|
| 사용자 식별 | 글로벌 계정 기준 | 글로벌 계정 연결 키 매핑 기준 | 동일 사용자로 정규화 후 병합 |
| 주문 상태 | 글로벌 상태 코드 | Breeze 상태 코드 | 공통 상태 코드로 매핑 |
| 금액 형식 | 소수점 포함 형식 | 정수 원화 중심 형식 | 노출 규칙 기준으로 통일 |
| 정렬 기준 | 주문 생성 시각 | 주문 생성 시각 | 날짜 역순(최신 우선) |
| 장애 대응 | 기본 소스 | 보조(브리지) 소스 | BLOHA 실패 시 글로벌 주문 우선 노출 |
데이터 흐름: 조회 요청에서 응답까지
사용자의 주문 내역 조회 요청이 글로벌 플랫폼의 API Gateway에 도달하면, 주문 서비스(Order Service)가 두 개의 병렬 호출을 수행한다. 첫 번째는 글로벌 주문 데이터베이스에서 해당 사용자의 주문을 조회하는 것이고, 두 번째는 BLOHA API를 호출하여 해당 사용자의 Breeze 과거 주문을 조회하는 것이다. 두 번째 호출에서는 사용자의 글로벌 계정 연결 키를 사용하여 Breeze 계정의 주문을 찾는다.
두 결과가 모두 도착하면, 병합 로직이 실행된다. Breeze 주문의 필드를 글로벌 주문의 필드 형식으로 변환(매핑)하고, 모든 주문을 날짜 역순(최신 주문이 위)으로 정렬하여 하나의 목록으로 만든다. 이 목록이 사용자에게 반환된다.
스키마 매핑의 과제
Breeze 주문 데이터를 글로벌 형식으로 매핑하는 것은 BLOHA 응답을 그대로 전달할 수 없다는 것을 의미한다. BLOHA는 Breeze 스키마 그대로 데이터를 반환하고, 이를 글로벌 형식으로 변환하는 것은 호출하는 쪽(글로벌 주문 서비스 또는 BFF)의 책임이다.
매핑이 필요한 주요 항목들: 주문 상태 코드(Breeze 코드 → 글로벌 코드), 날짜/시간 형식(KST → UTC 또는 사용자 타임존), 금액 형식(정수 원화 → 소수점 포함 형식), 상품 정보(Breeze 상품 코드 → 글로벌 SKU), 배송 상태(Breeze 배송 코드 → 글로벌 배송 상태). 각 매핑에는 예외 케이스가 존재했고, 매핑할 수 없는 값(deprecated 코드 등)에 대한 폴백(fallback) 로직도 필요했다.
성능 고려: 두 소스의 병렬 조회
두 데이터 소스를 순차적으로 호출하면 응답 시간이 두 배로 늘어난다. 따라서 글로벌 주문 조회와 BLOHA 호출을 병렬로 수행하여 응답 시간을 최소화했다. 두 호출 중 느린 쪽의 응답 시간이 전체 응답 시간을 결정한다.
BLOHA의 응답 시간은 특히 중요했다. 관계형 DB에서 특정 사용자의 주문을 조회하는 쿼리의 성능이 전체 사용자 경험에 직접 영향을 준다. BLOHA DB에 적절한 인덱스가 설정되어 있어야 하고, 대량 주문 이력이 있는 사용자(예: 수백 건의 주문)에 대한 페이지네이션도 고려해야 했다.
핵심 기술 스택과 선택 이유
| 구성 | 선택 이유 | 대안 | 트레이드오프 |
|---|---|---|---|
| 병렬 조회(글로벌 + BLOHA) | 주문 조회 지연을 최소화 | 순차 조회 | 구현 복잡도 증가 대신 체감 성능 개선 |
| 매핑 계층(BFF/Order Service) | 이질 스키마를 단일 응답으로 통합 | 원천 스키마 노출 | 매핑 규칙 관리 비용 증가 |
| 타임아웃 + 서킷브레이커 | BLOHA 장애의 전파 차단 | 무제한 재시도 | 일부 과거 주문 일시 미노출 허용 필요 |
BLOHA 장애 시 우아한 저하(Graceful Degradation)
BLOHA가 일시적으로 응답하지 않는 경우에도 사용자의 주문 내역 조회가 완전히 실패해서는 안 된다. 글로벌 주문 데이터만이라도 표시하고, 과거 주문은 ‘일시적으로 조회할 수 없습니다’ 같은 메시지를 보여주는 우아한 저하(graceful degradation) 전략이 필요했다.
Graceful Degradation은 일부 기능이 실패해도 핵심 사용자 흐름을 유지하는 전략이다.
주의: BLOHA 장애 시에도 전체 주문 조회를 실패시키지 않도록 축소 응답 경로를 반드시 유지해야 한다.
이를 위해 BLOHA 호출에는 타임아웃과 서킷브레이커(circuit breaker) 같은 실패 격리 패턴을 적용했다. BLOHA가 일정 시간 내에 응답하지 않으면 타임아웃으로 처리하고, 연속 실패가 감지되면 호출을 제한해 글로벌 주문 조회 전체로 장애가 전파되지 않도록 했다.
글로벌 전환은 단순한 데이터 이동이 아니라 경계와 책임을 다시 정의하는 작업이었다는 점이 이 시리즈의 중심에 있다. 다음 글에서는 2021 - CS 조회, 반품, 배송 상태 동기화는 왜 같이 풀어야 했나를 통해 이 흐름을 계속 좁혀 본다.
아키텍처 대안과 트레이드오프
대안은 과거 주문을 새 플랫폼으로 전량 이관하는 방식과, 브리지 서비스로 분리 조회하는 방식이었다. 전량 이관은 장기적으로 구조가 단순해질 수 있지만, 전환 시점 리스크와 검증 비용이 크게 증가한다. 브리지 방식은 단기 복잡도는 늘지만 컷오버 리스크를 낮출 수 있다.
이 글의 구조는 후자를 선택했을 때 필요한 운영 설계를 보여준다. 핵심은 “두 소스를 함께 쓰는 복잡도”를 허용하되, 사용자 경험은 단일 주문 조회처럼 유지하는 것이다.