pile·
백엔드·마켓컬리마켓컬리 Hello World·

주소정제 서비스 내재화 - 마지막 화 ( 엔드 게임 )

컬리가 약 10개월에 걸쳐 주소정제 서비스를 내재화한 여정의 마지막화다. 외부 업체 API 호출을 전체의 1% 미만으로 줄여 2024년 9월 30일 계약을 종료했고, 마지막까지 남은 지번 주소와 LOW 레벨 주소 두 케이스를 처리한 방법과 프로젝트 회고를 담는다.

핵심 포인트
  • 외부 호출을 1% 미만으로 줄이고 2024-09-30 외부 업체 계약을 종료했다.
  • 남은 지번 주소 요청(하루 약 20건)은 행안부 도로명주소 조회 API로 우회했다.
  • LOW 레벨(철거 건물·행정구역 변경)은 변경 이력 DB를 만들어 해결했다.
  • 최종 버전은 2024년 8월 배포, 이후 2달간 외부 인터페이스 없이 운영하며 검증했다.
  • 두 DB 어디에도 없는 주소만 처리 불가로 응답하며, 정상 주소를 오분류한 사례는 없었다.
상세 정리
  • 지번 배경: 지번 주소 요청은 하루 20건 수준으로 줄어, 별도 지번 DB 구축은 과설계로 판단했다.
  • 지번 해결: 요청을 AddressSearchParam으로 변환하고 isJibunAddress()/isRoadAddress() getter로 유형을 구분, 지번이면 행안부 도로명 조회 API로 건물관리번호를 얻어 내부 건물 DB를 조회한 뒤 도로명 처리 로직을 태운다.
  • 지번 결과: 현재까지 문제없이 동작한다.
  • LOW 케이스1(철거): reasonCode=63인 철거 예정 건물은 외부 호출하면 안 된다. 외부 업체의 오래된 응답으로 배송기사가 없는 건물을 찾아가 배송 실패가 날 수 있어서다.
  • LOW 케이스2(행정구역 변경): 동탄2신도시 도로명 변경(동탄대로→동탄역로)이나 관할 개편처럼 시민이 앱 주소를 곧바로 갱신하지 않는 경우다.
  • LOW 해결: OMS 일배치로 기준 대비 속성 변경을 감지해 이전 값을 변경 이력 DB에 저장한다. 기본 건물 DB 조회 실패 시 이력 DB에서 건물관리번호를 꺼내 현재 기준으로 정제한다.
  • 과거 이력 보완: 구현 이전의 변경분은 기록이 없어, 백오피스로 이력을 수동 추가·수정·삭제했다. 하루 1~2건씩 3개월 처리하니 양이 줄었다.
  • 예외 처리: 두 DB 모두에 없는 주소만 처리할 수 없는 주소 예외를 던진다. 정상 주소를 오분류한 케이스는 관측되지 않았다.
  • 검증: 8월에 정상 주소가 외부 호출을 유발하는지 감사, 9월에 외부 인터페이스를 완전히 제거하고 안정성을 관찰했다. 2달간 무결.
  • 회고(아쉬움): 건물 DB를 먼저 구축했다면 개발이 빨랐을 것, 저빈도 엣지 케이스를 허용 실패 기준 정의보다 먼저 쫓은 점, 서버 로그 수동 검증이 번거로웠고 지도 기반 백오피스가 대응력을 바꿨다.
  • 회고(성공): 단독·복합 건물 로직 초기 분리, 1588-0061(7자리 도로명 안내) 활용, LOW/HIGH 정확도 레벨 도입, 업체를 능가하는 기능 구현, 90% 감축 후에도 남은 10%까지 밀어붙인 점.
  • 성과 정의: 90% 감축에서 멈추지 않고 남은 10%인 지번·LOW 케이스까지 해결해 외부 호출을 1% 미만으로 낮춘 것이 계약 종료의 근거가 됐다.
왜 읽나외부 벤더 API를 내재화해 완전 대체하려는 백엔드 엔지니어에게 마지막 10% 엣지 케이스 처리와 계약 종료 검증 절차의 실전 레퍼런스.
마켓컬리
마켓컬리 Hello World 블로그
원문은 여기서 이어서 읽을 수 있어요
원문 읽기
읽음 (0)

이 글과 비슷한

  1. 백엔드·github-engGitHub Engineering·

    조기 종료를 없애야 벡터화된다 — 메모리 속도 소스 코드 케이스 폴딩

    GitHub의 코드 검색 엔진 Blackbird는 480TB 이상의 소스 코드를 인덱싱하기 전 모든 바이트에 case folding을 적용한다. 이 글은 Rust로 구현한 case folding을 메모리 대역폭 한계(45+ GiB/s)까지 끌어올린 두 가지 반직관적 최적화를 상세히 다룬다. 핵심은 루프 조기 종료(break) 제거로 LLVM 벡터화를 유도하고, UTF-8을 디코딩하지 않고 바이트 공간 산술만으로 fold를 수행하는 것이다.

    #rust#unicode#simd+2
  2. 백엔드·여기어때 (GC컴퍼니)여기어때 (GC컴퍼니)·

    트랜잭션 스크립트에서 숙소 메타 + 가격 계산 모듈로 — 전시 아키텍처 개선기 (2/3)

    여기어때 전시개발팀이 숙소 상세(PDP) API를 해부한 결과, 코드상으로는 DB 호출 3번처럼 보이던 요청이 실제로는 MongoDB $lookup 체인으로 컬렉션을 19회 접근하는 구조였다. 이 트랜잭션 스크립트 방식의 핵심 문제는 "aggregation이 I/O를 가린다"는 점으로, 독립적인 쿼리 10개가 단일 파이프라인에 직렬화되어 병렬화 기회를 잃고, 가격 때문에 거의 안 바뀌는 이미지까지 매 요청마다 읽어야 하는 읽기 증폭이 발생했다. V3에서는 "조회 시점 조립"을 "쓰기 시점 사전 조립"으로 전환하고, 화면별로 복제되던 가격 계산 로직을 goodsprice 단일 모듈로 수렴했다. 4개 API(PLP/PDP/RDP/ILP)의 반복 마이그레이션은 Claude Code skill로 절차를 고정하고 쉐도잉 + 동일성 검증으로 안전망을 마련하는 방식으로 진행됐다.

    #architecture#migration#caching+2