외부 시스템 장애에 대처하는 우리의 자세

Dec.02.2021 박주희

Culture

안녕하세요. 기술고도화팀 박주희입니다. 

‘한 아이를 키우려면 온 마을이 필요하다’라는 아프리카 속담 들어보신 적 있나요?
저는 이 속담이 IT업계에도 딱 맞는다는 생각을 자주 하게 되는데, 하나의 서비스를 잘 키우기 위해서 수많은 외부 시스템의 도움이 필요하기 때문입니다.

외부 시스템 연동은 왜 하나요?

필요한 모든 기능을 직접 개발하고 관리할 수 없기 때문에 각 기능에 맞는 외부 시스템과의 연동을 통해서 서비스를 운영하게 됩니다. 우아한형제들도 당연히, 여러 외부시스템의 도움을 받고 있습니다. 배달의민족 서비스를 예로 들어보면, 간편 로그인을 위한 소셜네트워크 서비스, 가게와 라이더의 위치를 보여주기 위한 지도 서비스, 결제를 위한 PG 서비스, 주문 상태를 사용자/사장님/라이더에게 알려주기 위한 메시지 서비스 등, 수많은 외부시스템의 도움을 받고 있습니다. (문자 발송이 필요하다고 통신사를 세울 수는 없잖아요?)

딜리는 엘리베이터라는 외부시스템의 도움을 받기도 합니다.

이런 외부 시스템 연동은 직접 개발하고 운영하는 것에 비해서 비교적 간단한 연동 작업으로 높은 수준의 서비스를 이용할 수 있으며, 비용 측면에서도 직접 구축하고 운영하는 것보다 훨씬 저렴합니다. 하지만, 이런 외부 시스템은 우리의 통제 범위 밖에 있는 불안 요소로 인해 우리 서비스에 치명적인 영향을 줄 수 있기 때문에 신중한 결정과 연동이 필요합니다.

그래서, 오늘은 우아한형제들이 안정적인 서비스 제공을 위해서 어떻게 외부 시스템을 연동하고 있는지, 어떤 고민을 하고 있는지 공유해 보려고 합니다.

외부 시스템 장애로 인해 힘들었던 지난날… 아니, 현재진행형

2018년 2월 IDC 정전

2018년 2월의 어느 날 한가로운 아침, 출근 전 여유롭게 티타임을 즐기고 있던 시간.
갑자기 메인 DB로 접속이 안 된다는 알람과 문의가 빗발치기 시작했습니다.

마시던 커피를 그대로 두고 얼른 자리로 뛰어가 DB에 접속을 시도하는데, DBA도, SE도 아무도 접속을 할 수 없는 이상한 상황이 발생했습니다. 담당자분들은 출근해서 짐도 풀기 전에 IDC로 달려.. 아니 날아가셨고, 남아있는 사람들은 계속해서 접속을 시도하면서 초조한 시간을 보내고 있었습니다. 처음에는 우리 장비에 문제가 생긴 게 아닐까 걱정하다가 IDC가 정전되었다는 이야기를 듣고 더 큰 혼란에 빠져버렸습니다. 난생처음 맞닥뜨린 상황에 당황스러워서 이런 일이 자주 있는 건지 주위를 둘러보았는데, 그때 옆에서 한 분이 ‘이 바닥 15년 넘었지만, IDC 정전은 또 처음이네..’라고 조용히 읊조리시는 모습에 고개를 끄덕일 수밖에 없었습니다.

다행스럽게도(?) 점심시간 전에 서비스가 정상화되어서 사장님들의 점심 장사를 망치지는 않았지만, 그 뒷수습을 하느라 며칠을 신경 쓴 기억이 생생하게 남아있습니다.

2018년 11월 클라우드 서비스 장애

그리고 같은 해 11월의 정신없는 출근길.
이번에는 클라우드 서비스에 접속할 수 없다는 제보가 장애 대응 채널에 마구 올라오기 시작했습니다.

처음에는 일부 기능에만 문제가 생긴 줄 알았지만, 콘솔에도 접근할 수 없는 상황인 것이 확인되었고, 한국에서 해당 클라우드 서비스를 사용하고 있는 모든 업체의 앱들이 정상 동작하지 않는다는 제보가 줄을 이었습니다. 이런 상황에서 클라우드 서비스 업체의 ‘정상화되었다’는 한 마디를 기다리는 일 외에는 할 수 있는 게 거의 없다는 것에 많은 분이 힘들어했습니다.

하지만, 클라우드 서비스 장애로 대부분의 국내 앱들이 동작하지 않는 가운데, 배달의민족은 앱에 적용된 오프라인 모드 덕분에 사용자의 스마트폰에 저장된 캐시를 통해 일부분 서비스를 이용할 수 있었습니다. (지난 장애에서 배운 점을 빠르게 적용한 결과였습니다)

그리고 그 후…

그 후에도 여전히 크고 작은 외부 시스템 장애는 끊임없이 생기고 있습니다. 2020년 특정 외부 SDK 장애로 인해서 아이폰 앱에서 튕김 현상이 발생하여 1시간 넘게 서비스가 불가능했던 장애에서부터 최근 통신사의 라우팅 장애에 이르기까지 많은 외부 시스템 장애에 여전히 고통받고 있습니다.

하지만 마냥 손 놓고 기다릴 수는 없기 때문에, 주어진 환경 아래에서 우리가 할 수 있는 최선의 방법을 계속 고민하고 개선해 나가고 있습니다. 특히, 우아한형제들에서는 사용자가 인지하지 못하는 작은 범위의 외부 시스템 장애라고 하더라도 이를 내부적으로 모두 공유하고 있는데, 이는 빠른 대응을 통해 고객 불편을 최소화하기 위함입니다. 소소하게는 PG서비스 장애, 지도 서비스 장애, 메시지 서비스 장애 등등등 셀 수 없이 많은 장애를 만나고 있으며, 최근 지표에 따르면 2021년에 발생한 장애 중 45% 이상의 장애가 외부 시스템 영향으로 발생했습니다.

외부 시스템 의존성 조사

외부 시스템 장애로 인한 고통을 조금이라도 덜어보고자, 2020년부터 우아한형제들에서는 외부 시스템 의존성 조사를 진행하고 있습니다.

서비스가 커지면서 외부 시스템 이슈로 인한 장애 빈도가 잦아졌고, 그로 인한 영향도 또한 커졌기 때문에 우리가 기대고 있는 서비스들에 대한 가시화가 필요했습니다. 2020년 조사 후에는 여러 시스템에서 이중화 작업과 불필요한 의존 관계를 끊어내는 작업이 진행되었고 그로 인한 시스템 안정성 향상 효과를 확인했습니다. 2021년에는 각 연동 시스템들이 모니터링이 잘 되고 있는지, 지난해 외부 시스템의 장애 빈도는 어땠는지 등의 내용을 추가해서 현행화하는 작업이 진행되었습니다.

주요 수집 항목들을 살펴보면,

외부 시스템 정보

  • 명칭
  • 제공 업체 정보
  • 2020년 장애 발생 횟수
  • 사용 보편성 (국내외에서 얼마나 많은 업체가 해상 서비스를 사용하고 있는지)
  • 갱신 주기 (인증서 갱신, 데이터 갱신, API key교체 등이 필요한 서비스의 갱신 주기)

내부 서비스 정보

  • 담당팀
  • 유발 장애 등급 (내부 장애 등급 분류표를 기준으로, 해당 시스템 장애 시에 발생할 수 있는 최고 장애 등급)
  • 알람 채널
  • 모니터링 수단
  • 로그 정보
  • 의존성 약화 or 제거 방안
  • 현재 상태
  • 목표 상태

이 조사를 통해서 우리는 리스크를 가시화하고, 전사적으로 퍼져있는 연동 내역을 확인해서 플랫폼화 가능한 요소들을 도출해 내며, 연동 방법에 대한 지식을 공유합니다. 우리 서비스가 아니라고 모른 척하기엔 우리 서비스에 미치는 영향이 너무 크기 때문에 항상 관심을 기울이고 더 나은 방법을 고민하고 있습니다. 

외부 시스템 연동 시, 주의해야 할 점은 무엇인가요?

외부 시스템 문제로 장애가 발생하면, (우리는 너무 억울하지만) 고객은 이를 인지할 수 없기 때문에 우리 서비스에 대한 고객 경험 하락과 함께 부정적인 인식이 생길 수 있습니다. 그렇기 때문에 외부 시스템을 연동할 때는 반드시 그 시스템의 장애가 우리 서비스 장애로 이어지지 않도록 주의를 기울여야 합니다. 조금의 장애도 발생하지 않는 서비스는 없기 때문에 항상 외부 시스템의 장애를 염두에 두고 연동해야 하며, 해당 시스템 장애 시에 우리 서비스의 영향 범위를 최소화할 수 있는 고민이 필요합니다. 

그럼, 외부 시스템 장애를 회피할 수 있는 몇 가지 방법을 살펴보겠습니다. 

의존성 제거

처음에 외부 시스템을 연동할 때는 이 연동이 꼭 필요한지 고민해 봐야 합니다. 연동된 시스템의 장애로 인해 우리 서비스가 직접적인 영향을 받는 경우에는 필요한 기능이 서비스 안정성에 우선하는지 비교해 보고 판단해야 합니다. 연동하고자 하는 외부 시스템의 안정성을 신뢰할 수 있는지, 연동을 통해서 얻고자 하는 목적이 뚜렷한지, 리스크를 감수할 만큼의 가치가 있는지 등을 명확히 하는 것이 중요합니다. 반드시 필요한 기능이 아니거나 대체할 방법이 있다면 의존 관계를 맺지 않는 것이 우리 서비스의 안정성을 높일 수 있는 가장 쉬운 방법입니다. 예를 들어, 마케팅을 위해서 외부 시스템과 연동을 해야 한다고 가정했을 때, (다소 극단적이지만,) 그 외부 시스템으로 인해 앱 전체에 장애가 발생할 가능성이 있다면 마케팅을 통한 이득과 앱 장애로 인한 손해를 비교해 보고 연동을 결정해야 합니다.

추가로, 이미 연동해서 사용 중인 시스템이라고 하더라도 주기적으로 적합성을 살펴보는 관심이 필요합니다. 서비스가 커지고 구조가 변경되면, 외부 시스템을 통한 이득은 변하지 않지만 리스크가 더 커지는 경우가 있고, 필요한 곳이 더 늘어나면서 연동 대상이 변경되거나 내부에서 직접 구현하는 경우도 있습니다. 이런 변화를 눈여겨보고 적절한 시점에 의존성을 제거해 주는 것이 좋습니다. 

벤더 이중화

일반적으로 널리 사용되는 서비스의 경우 여러 업체에서 비슷한 기능을 제공하는 경우가 많습니다. 동일한 기능을 제공하는 여러 벤더 사가 존재하는 경우에는 벤더 이중화 (혹은 다중화)를 통해서 장애를 회피할 수 있습니다. PG 서비스, 지도 서비스, 문자 서비스 등이 벤더 이중화에 적합한 케이스이며, 일반적으로 필수 기능은 동일하게 제공하기 때문에 이중화 구현이 가능합니다. 벤더 이중화를 구현할 때는 자동으로 전환되는 것이 가장 좋지만, 현실적으로 불가능한 경우가 많기 때문에 장애 시간을 최소화할 수 있도록 벤더 간의 전환이 간단하게 동작할 수 있게 구성하는 것이 중요합니다. 개발자가 반드시 개입해야 하는 구조보다는 어드민에 전환 기능을 구현해두고 권한이 있는 다수의 팀원이 조치할 수 있도록 구성하는 것이 일반적입니다.

벤더 이중화를 할 때 한 가지 주의해야 할 점은 이런 벤더 전환이 장애 발생 시에만 동작하기 때문에 전환 대상인 벤더 사의 사용 빈도가 극도로 낮다는 점입니다. A가 메인, B가 서브인 경우 B의 사용 빈도는 1년에 몇 차례 되지 않습니다. 어쩌면 한 번도 안 쓸 수도 있습니다. 이런 경우, 장애가 발생해서 이중화된 벤더 쪽으로 트래픽을 전환했지만, 해당 벤더의 연동 스펙이 변경되면서 연동이 정상적으로 동작하지 않아 장애가 해소되지 않는 맹점이 발생할 수 있습니다. (실제로 있었던 케이스이기도 합니다)  그렇기 때문에 이중화를 한 경우라도, 일정 비율을 두고 양쪽 벤더를 모두 사용할 수 있도록 연동하는 것을 추천합니다. 9:1 혹은 8:2의 비율로 전환 대상 서비스와도 상시로 트래픽을 주고받아서 연동 상태를 늘 체크할 수 있도록 하는 것이 좋습니다. 

장애 격리

외부 시스템을 연동하다 보면 이중화를 고려할 만큼 서비스가 크지 않거나, 이중화에 비용이 너무 많이 들거나, 이중화 할 수 있는 다른 벤더가 없는 경우 등, 여러 이유로 이중화가 불가능한 외부 시스템도 당연히 존재합니다. 이런 경우에는 외부 시스템의 장애가 연동과 관련 없는 부분으로 전파되지 않도록 장애를 격리하는 것이 중요합니다. 특정 기능이 일부 동작하지 않거나 기능이 저하되더라도 사용자가 최소 기능을 사용할 수 있도록 제공하는 것이 핵심입니다. 예를 들어, 특정 프랜차이즈나 배달 대행사 시스템에 장애가 발생하는 경우에는 해당 연동 시스템을 사용하는 업소의 주문 처리가 불가능해집니다. 이때 빠르게 대상 업소들을 주문 불가 상태로 변경을 해서 사용자들이 주문 취소나 지연을 경험하지 않도록 하고, 내부적으로는 에러 처리가 늘어나지 않도록 조치하게 됩니다. 

물론, 이런 장애 격리는 이중화되어 있는 서비스에도 적용될 수 있는데, 연동 전환 간에 발생하는 찰나의 순간에도 고객의 불편함을 최소화하는 조치입니다. 예를 들어, 포장 서비스에서 가게 위치를 표시해 주는 기능이 있는데, 지도 서비스에 문제가 생겨서 지도를 정상적으로 불러오지 못하는 장애가 발생하더라도 전체 가게 상세 페이지로 전파되지 않도록 격리가 필요한 것입니다. 자주 가는 곳이라면 사용자는 지도가 없더라도 가게 위치를 알 수 있기 때문에, 사용자가 사용하고자 하는 기능(주문)이 가능하도록 지도를 제외한 페이지를 보여주거나 지도를 정상적으로 불러올 수 없다는 적절한 에러 메시지를 노출해 주는 것이 하나의 방법일 수 있습니다. 

미작동 감내

의존성 제거, 벤더 이중화, 장애 격리 세 가지 방법으로도 장애 회피가 불가능한 경우가 있을 수 있습니다. 가장 대표적인 예가 AWS, GCP 등과 같은 클라우드 서비스입니다. (사용하지 않을 수도 없고, 현재로서는 장애를 회피할 수도 없습니다) 이런 경우에는 외부 시스템의 장애를 감내해야 하는데, 이때에도 장애 상황을 빠르게 인지할 수 있도록 모니터링을 강화하고 해당 서비스 담당 부서에 빠르게 확인할 수 있는 핫라인을 운영하는 등의 추가 조치가 필요합니다.

마무리

외부 시스템의 장애를 완벽하게 제거하는 것은 불가능합니다.
하지만 이를 사전에 알고 적절한 조처를 함으로써 그 영향 범위를 줄여나가는 것은 여전히 중요합니다. 외부 시스템을 연동할 때는 충분히 고민해 보고, 잘 지켜보고, 빠르게 대응할 수 있도록 많은 노력을 기울여야 합니다.