[WHY 시리즈 1] E.010 — 외부 서비스 장애

Mijeong (Rachel)
7 min readAug 11, 2019

--

‘코드와 서비스 만들기를 좋아하는 소프트웨어 엔지니어’로 일하고 있다. 엔지니어는 문제를 해결하는 사람이다. 문제를 해결하는 과정에는 여러 가지 선택이 존재할 수 있다. 가능한 최선의 결과를 위해, 항상 내 선택의 Why에 답할 수 있는 사람이 되고자 한다. 매주, 한 주 동안 내가 결정한 선택의 Why에 대해 정리하고자 한다.

프로덕트 런칭 후 약 3개월의 시간을 보내면서 숨 가쁘면 숨 가쁘다고 할 수 있는 다양한 상황들을 맞닥뜨렸지만 최근 1주일은 정말 그러했다. 우리 시스템 내에서 당장 손을 쓸 수 없는 장애 상황부터, 플랫폼 팀 리드라는 역할 내에서 일과 사람의 관리라는 관점에서 깊어지는 고민까지 종합 장애 세트같은 느낌이었다. 특별히 힘들었던 한 주를 그냥 흘려보내지 않기 위해 한 주 동안 겪었던 장애 상황에 대해 WHY를 던져본다.

Why?

1. 라이더 관리 외부 서비스 장애

우리 프로덕트도 사용자가 몰리는 피크타임이 존재한다. 혹, 프로모션이 진행되면 당연히 평소보다 트래픽은 더욱 몰리기 마련이다. 여느 때처럼 점심시간 전 피크타임을 보내고 있었고 지금까지 큰 문제 없이 서비스가 제공되고 있었기에 평소처럼 점심을 먹으러 나갔었다. 밥이 나오자마자 슬랙에서 urgent issue라며 여기저기 노티가 오기 시작했다. 우리 프로덕트의 핵심은 ‘사용자 — 라이더 — 상점’ 간의 상호작용을 통해 하나의 주문을 완성하는 것인데, 이 중 라이더 관리 외부 서비스에 장애가 발생하면서 많은 수의 주문이 처리되지 못한 것이다.

  • Why? 라이더 관리 외부 서비스에서 스케일업/스케일아웃에 대한 대비가 부족했다. 우리 프로덕트의 트래픽이 증가하는 것은 곧 라이더 관리 외부 서비스에 대한 트래픽도 증가한다는 것을 의미한다. 우리 프로덕트의 트래픽이 평소 피크타임보다 증가했고, 해당 외부 서비스의 DB 서버 CPU 사용량이 100%에 도달하면서 쿼리 시간이 길어지고, 이들의 로드 밸런서는 우리 프로덕트에게 타임아웃 에러를 반환했다.
  • Why? 라이더 관리 외부 서비스에서 우리 프로덕트에게 에러를 반환했지만 실제로는 요청한 job을 생성함으로써 일관성을 깨뜨렸다. 우리는 해당 외부 서비스에서 에러를 반환받았으니 요청한 job이 생성되지 않았다고 판단하여 주문을 생성하지 않았다. 하지만 실제로 라이더들은 job을 할당받고 주문 프로세스를 진행하는 일이 벌어진 것이다. 그들의 로드 밸런서의 타임 아웃에 걸려 에러를 반환했지만, 실제로는 길어진 쿼리 시간 이후에 요청에 해당하는 job을 생성한 것으로 추측(?)했다.
진작 했으면 얼마나 좋아.png

프로덕트를 만드는 엔지니어 입장에서 외부 서비스에게 ‘너희 절대로 장애 내지마’ 라고 말할 수는 없다. 다만, 외부 서비스의 장애로 인한 장애 상황을 겪고 나니 우리 입장에서도, 그들의 입장에서도 아쉬운 점은 분명 존재했다.

  • 그들에게 아쉬운 점 1. 수요일 피크타임에 발생한 장애 상황이 목요일 피크타임에도 동일하게 발생했다. 우리 입장에서는 그들이 현 장애 상황을 심각하게 인지하지 않았거나, 정확한 원인 분석을 위한 시도를 안 했다고 밖에 생각할 수가 없었다.
  • 그들에게 아쉬운 점 2. 장애 상황이 발생한 후의 프로세스가 체계적이지 않았다. 장애 상황이 복구된 것은 당연해야 하고, 그들의 서비스를 이용하는 우리 입장에서는 ‘원인’과 ‘해결책’에 대한 상세한 내용을 전달받지 못한다면 또다시 이런 장애 상황이 발생할 것이라고 의심할 수밖에 없다. 첫 장애 발생 시 해당 내용에 대해 구체적으로 전달받지 못했으나, 다행히 두 번째 장애 발생 시 해당 내용에 대해 전달받을 수 있어서 다행이었다.

그래도 스카이프 채널을 통해서 우리의 요구사항을 실시간으로, 그리고 높은 우선순위로 처리하는 것을 확인했기에, ‘그래, 함께 성장해가는 입장에서 같은 실수는 더 반복하지 않으면 되지’ 라고 살짝 너그러운 척을 하기도 했다.

영어가 짧아서 더 화난 것처럼 보이는 것뿐임.png
  • 우리 스스로 아쉬운 점 1. 외부 서비스의 영향에도 운영하기에 유연한 구조로 프로세스를 설계하지 못했다는 생각을 했다. 우리 프로덕트의 주문은 라이더의 존재 없이는 진행될 수 없기에, 라이더 job이 생성되지 않으면 주문 자체도 생성되지 않는 구조로 설계했다. 하지만, 이번 장애를 겪고 난 후 외부 서비스는 우리의 관리 영역 밖이고 어떤 상황이 발생할지 예측하기 어렵기에 사용자가 시도한 주문 생성은 모두 우리 프로덕트 내에서 확인할 수 있어야 한다는 방향으로 프로세스를 수정했다.
  • 우리 스스로 아쉬운 점 2. 외부 서비스에게 아쉬운 점과 동일하게 우리 역시 장애 상황이 발생한 후의 프로세스가 체계적이지 않았다. 프로덕트 팀은 프로덕트 팀 대로 외부 서비스와 커뮤니케이션 하고, 운영 팀에서는 운영 팀 대로 외부 서비스와 커뮤니케이션 하면서 정보가 모이지 않거나 혹은 불필요한 커뮤니케이션이 진행됐다. 이번 상황을 계기로 우리 역시 장애 상황에 대한 프로세스를 체계적으로 잡아갈 예정이다.

2. 쿠폰 관리 외부 서비스 문제

안 좋은 일은 한 번에 온다고 했던가. 라이더 관리 외부 서비스 장애가 발생했을 때 동시에 쿠폰 관리 목적으로 사용하던 외부 서비스에도 문제가 발생했다. 정확히 이야기하면 쿠폰 관리 외부 서비스는 장애가 아니고, 우리의 계약 플랜에 따른 limit 초과 문제였다. 대부분의 주문이 쿠폰을 사용한 주문인 호찌민 시장에서 쿠폰 사용을 할 수 없는 상황 역시 치명적이었다.

  • Why? 쿠폰 관리 외부 서비스 사용 시 계약 플랜에 따른 API call 횟수 limit이 존재했고, 당시에 해당 limit을 초과했다. 일반적으로 시간당 API call은 기존 limit의 반도 안 되는 수치였지만, 특정 시간대에만 유난히 API call 횟수가 많아서 외부 서비스를 이용할 수 없게 된 것이다.
  • Why? 쿠폰 관리 외부 서비스를 사용하면서 사용 현황에 대한 분석이 없었다. 결국 문제가 발생하고 나서 그동안의 외부 서비스 사용 현황을 분석하고, 현재 계약한 플랜의 업그레이드가 필요할지 아닐지 판단해야 했다. 결론적으로 쿠폰이 valid 한지 확인하기 위한 외부 서비스 API call이 많은 부분을 차지했고, 외부 서비스에 대한 API call 없이도 우리 시스템 내에서 쿠폰의 valid 여부를 확인할 수 방향으로 로직을 개선하기로 결정했다.
urgent 한 번에 내 수명 단축되고.png

적은 리소스로 빠르게 프로덕트를 런칭하기 위해서는 적절한 외부 서비스의 사용이 필요했다. 그들의 서비스를 통해 우리 프로덕트의 핵심에 더 집중하여 개발할 수 있었고, 여러가지 운영 편의성의 장점도 얻고 있다. 하지만, 예상했던 대로 그들의 서비스는 우리의 관리 영역 밖이고 각 서비스마다 계약에 따른 사용 현황을 지속적으로 확인해야 한다는 불편함도 존재한다. 이번 장애 상황이 ‘아 됐고 자체 시스템으로 구축하자’라는 생각에 도달하지는 않았다. 오히려, 여러 서비스에 의존성이 있는 상황이니 장애 상황에 대한 구체적이고 체계적인 프로세스 수립이 중요하다는걸 다시 한번 깨닫게 된 것이다.

일요일 저녁, 글을 쓸까 아니면 못다 한 데이터 스크립트 작업을 할까 고민했지만, 글을 쓰고 보니 복잡했던 머리와 마음이 조금은 정리된 기분이다. 다음 글에서는 일도 많아지고 사람도 많아지는 환경에서 플랫폼 팀 리드 역할을 잘 해내 보고 싶은 마음에 몰아치는 고민을 한 번 정리해볼까 한다.

프로덕트 팀 첫 회고 후기도 작성해야 하는데.. 📝

행복했던 프로덕트 팀 첫 회고.png

--

--

No responses yet