주소정제 서비스 내재화 - 2화 ( 그럴싸한 계획 )

손 안대고 코풀기 전략의 한계

주소정제 내재화 전체 과정
주소정제 내재화 전체 과정
(그림: 컬리, © 2023. Kurly. All rights reserved.)

앞서 1화에서는 도로명 주소의 특징과 컬리에서 주소정제가 어떤 의미를 갖는지에 대한 설명이었습니다.

그리고 건물은 단독건물과 복합건물로 나누어 생각해볼 수 있었습니다.

상세주소를 참고해야 정확한 건물정보, 위경도를 알수 있는 복합건물은 일단은 제외하고, 기본주소의 건물번호까지의 정보만으로 건물을 특정할 수 있는 단독건물 주소 정제를 먼저 진행하기로 결정했습니다.

2화는 23년 5월 ~ 8월까지 약 3개월 동안 도로명 주소에 대해 학습한 도메인지식, 그리고 여러 레퍼런스를 통해서 1차 주소정제 1.0 을 설계하고 운영환경에 랜딩하는 과정을 설명합니다.

제 기억에 이 때 까지는 외부 업체와의 계약 종료라는 목표는 뭔가 멀게만 느껴지는 목표였고, 일단 외부업체 api 호출 비용이라도 가능한 최소한으로 줄여보자를 목표로 계획을 세웠습니다.




행안부 오픈 api 발견

여러 리서치 끝에 행정안전부 오픈 api 하나를 발견하였습니다.

행안부 제공 API
행안부 도로명 주소 조회 api
(그림: 컬리, © 2023. Kurly. All rights reserved.)

파라미터에 도로명이나 지번주소를 그대로 넣으면 도로명주소, 지번주소, 건물관리번호를 포함한 의미있는 응답을 제공하고 있습니다. 도로명주소에 필수 기준값인 가장 중요한 25자리의 건물관리번호도도 ( bdMgtSn ) 제공합니다.

다만, 위 도로명주소 조회 api에서는 위경도 정보가 없어서 정말 아쉬웠는데요.

아주 럭키하게도 위 응답값 중 도로명코드, 건물본번, 건물부번 정보를 파라미터로 던지면 위경도를 응답해주는 api도 발견했습니다.

행안부 제공 위경도 api
행안부 제공 위경도 api
(그림: 컬리, © 2023. Kurly. All rights reserved.)

위 응답값 중 entX, endY 두 값이 GRS80 UTM-K 좌표계 형태의 위경도이고, 이를 우리가 알고있는 지리적 위경도로 변환만 하면 건물의 위경도까지도 커버가 가능했습니다.

혹시나 해서 행정안전부 담당자와 유선상으로 API 사용시 주의사항도 체크해 봤습니다.

  1. 행안부 도로명 주소조회 api ( 쿼티 제한없음)
  2. 행안부 좌표정보 api ( 5초당 10건 제한)
  3. 모든 api는 DOS공격, 자바스크립트 인젝션 등 보안상 사이버 공격으로 간주되는 요청들의 경우 IP차단될 가능성은 있음

이 중 3번에 대해 DOS공격에는 어느정도 수준인지 구체적으로 여쭤봤으나 명확한 답변은 얻지못했습니다.

어쨌든 좌표 조회 api는 5초당 10건 제한이라는 사실상 사용이 엄청 제한적임을 알게되었고, 도로명 주소조회 api는 행안부에서 명시한 지침대로 트래픽을 조절해서는 충분히 사용가능해 보였습니다.




건물이 같으면 당연히 같은 도로명 기본주소라는 정보를 활용

그렇다면 어떻게 건물의 좌표값을 얻을 수 있을까…

컬리에는 약 5년동안 외부 업체 호출 결과 꽤 많은 정제 된 주소정보 데이터를 가지고 있었고 이 데이터를 활용하면 꽤 많은 건물들의 좌표정보도 충분히 커버 가능할 것으로 보였습니다.

( 외부 업체와 계약당시 주소 데이터를 캐싱하여 호출량을 조절해도 괜찮다는 허락을 받음, 훔친게 아님 )

참고로 OMS 팀은 이 데이터를 '외부 주소정제 축적 데이터' 라고 표현합니다.

행안부 제공 위경도 api
회사 아이콘 제작자: srip - Flaticon

만약 어떤 주소 건물의 503호 거주 고객의 주소정제 요청이 왔을때 만약 '외부업체 주소정제 축적 데이터'에 이미 같은 건물관리번호로 다른 고객의 데이터가 있다면 그 값을 사용하면 활용하면 되지 않겠느냐?

위 아이디어를 검증하기위해 당시 운영환경에서 외부업체 api를 호출한 주소기준으로 무작위로 100개정도를 찍어서 주소정제가 어느정도로 커버가 될지를 가늠했고 충분히 가능성이 있어보였습니다.

(솔직히 오래되서 정확히 기억안남…100개까지 다 안해 본걸로 기억하는데 여튼 50개 이상 해보다가, 됐어 충분해! 하고 중단했던 기억은남. 꽤 많은 케이스 커버가 가능하다는 결론이 나옴)




그럴싸한 계획과 일찍 터트린 샴페인

위 아이디어를 바탕으로 아래와 같은 알고리즘 주소정제 1.0 flow를 그렸습니다. (글씨 작음 주의, 핀치 줌아웃 권장)

all_flow
주소정제 1.0 전체 flow
(그림: 컬리, © 2023. Kurly. All rights reserved.)

녹색 STEP1 을 보시면 됩니다. 회색은 기존의 주소정제 Flow

  • STEP 1. 행안부 도로명 주소조회 API를 통해 건물관리번호를 알아낸 후, 외부업체 주소정제 축척 DB에 건물관리번호로 정제 주소를 알아낸다.

  • STEP 2. 외부업체 주소정제 축척 데이터에 없을때는 행안부 좌표조회 api 활용도 시도해보자.

위 Flow가 충분히 가능할 것이라는 가설을 1차로 확정한 후 안전하게 운영에 랜딩할 수 있는 계획과 명확한 개발 기준을 정했습니다.

주소정제는 자칫 컬리몰 장애까지 이어질수 있는 리스크가 큰 서비스이기 때문에 굉장히 보수적으로 접근해야 합니다.

그럴싸한 계획

  1. 가장 먼저 AS-IS 로직에 테스트 코드 점검
  2. 개발기 기준으로 위 Flow 구현 ( 필요한 테스트 코드 추가, 기존 테스트 코드는 반드시 통과해야함 )
  3. 주소정제 응답 latency가 얼마나 증가하게 될 지 체크 (사용 가능 수준인지)
  4. QA 환경에서는 QA분들 도움을 받아서 컬리몰 장애까지 이어질만한 큰 버그가 없는지 체크
  5. 운영 카나리 배포 상황에서 최대한 패치버전을 검증하자. ( 최소 일주일은 모니터링 필요하고, 이 과정에서 발견된 에러가 간단하다면 핫픽스, 복잡하면 롤백 )
  6. 신규 패치 안정화 이후에는 지속적으로 또 다른 외부업체 호출 케이스들 분석하여 차근차근 잡아나가자 (1~4번 반복)

위와 같은 그럴싸한 계획을 통해 약 23년 8월, 최초 문제를 인지한지 3개월만에 주소정제 1.0이 운영환경에 랜딩 할 수 있었습니다.

효과는 굉장히 좋았습니다.

첫번째 작업 만으로도 외부업체 호출은 기존 호출대비 절반 이하로 줄일수 있었고, 비용으로 따지면 월 150~200만원을 아낄 수 있었습니다. 또한 이후 STEP 2를 진행하면 단일 건물의 대부분을 커버할수 있겠다는 자신감도 얻었습니다.

그것도 불과 문제를 인지한지 3개월만에 말입니다.



샴페인 다시 회수

운영배포를 한 후 일주일 정도가 지났을까…

평화로웠던 날의 저녁 21시 쯤 OMS 팀 슬랙 채널에 주문결제 팀의 김정명님의 다급한 어조의 문의가 들어왔습니다.

내용은 대충 이랬습니다. ( 관련 슬랙을 찾아보려 했는데, 슬랙 히스토리가 23년이 삭제가 되어 기억에 의존, 기억조작주의 )

  • 약 10분 동안 대략 1000건의 OMS api (내부적으로 주소정제 api를 호출을 하고있는)응답에서 에러가 발생헀다.

  • 모든 요청에 대해서는 아니고, 일부만 그렇다.

  • 진짜 문제는 고객경험이었는데, 만약 에러 응답을 받은 고객분들은 일시적 장애를 알리는 팝업을 보게되었을 것. 주문 결제를 진행 중이던 고객분들은 재시도를 해야했을 것.

대충 위와 같은 내용인데, 김정명님이 워낙에나 에러 상황을 실시간 중계를 해대면서 공포분위기를 조성했기에 황급히 원인을 확인해봤습니다.


문제 원인

  • 주소정제 1.0 설계에 추가된 행안부 도로명주소 조회 api 응답 latency가 약 5~10분 동안 타임아웃 에러 혹은 대부분 502 Bad gateway 응답

  • 메인 캐시에 존재하는 요청들은 정상응답 ( 1.0 주소정제 과정 없이 응답하기 때문 )

  • 메인 주소 캐시에 없던 주소요청이 장애 대상


"일단 롤백을 해야할까?"


팀 결정

  • 임시방편으로 위 문제를 해결하기 위해 행안부 도로명주소 조회 api 호출 타임아웃을 더 짧게 가져가도록 핫픽스 진행

  • retry 로직은 제거 (위와 같은 상황에서는 어차피 정상 응답을 받지 못할 확률이 높다)

  • 타임아웃 익셉션 발생시 무조건 기존 외부업체 호출 로직 태우도록 변경

그날 이후로도 비슷한 규모의 문제의 상황이 3번 정도 추가로 발생 했음을 핫픽스 배포에 포함시킨 에러 로그를 통해 확인되었습니다.

행안부 직원을 통해 원인을 물어봤으나 명확한 답변은 얻지못했고, 타임아웃을 보수적으로 걸어놓았기 때문에 핫픽스 이후에는 컬리몰 장애까지는 이어지지 않았습니다.



주소정제 1.0의 냉정한 평가

주소정제 1.0은 결과만 놓고 보면 짧은 시간에 작은 리소스만으로 꽤 많은 비용절감 효과를 낼 수 있었던 설계임에는 틀림없었습니다.

이 시점에 과연 장기적으로 옳은 방향의 설계였는가를 냉정하게 평가해봤습니다.

  • 도로명주소 조회 API 의 호출 안전성을 의심하지 않았다.

  • 외부업체 주소정제 축척 데이터 만으로는 대한민국의 모든 건물의 위경도를 커버할수 없다. ( 신규가입 고객분들의 주소 요청 때문에라도 외부업체와의 계약은 종료하지 못할 것 )

  • 이제는 외부업체 뿐 만아니라 행안부 api까지 챙겨야하는 관리포인트

과연 행안부 도로명주소 조회 api를 계속 활용하는 게 옳은 방향일까?

아마 외부업체 호출 계약종료 라는 원대한 목표는 '그냥 해본 소리에요~' 정도 였구나로 평가될 것이 분명해 보였습니다.

결과적으로 손 안대고 코를 풀수 있는 방법따윈 없었고 고민 끝에 현재 상태 프리징 후 새로운 방법을 찾기로 결정 했습니다.

3화 노가다의 달달한 열매 보러가기