Sean Goedecke의 글 Notes on incidents는 장애 대응에 관한 통념을 뒤집는다. 장애가 발생하면 누군가 즉시 원인을 찾아내고, 재치 있는 수정으로 시스템을 구해야 한다고 생각하기 쉽다. 하지만 실제 장애 대응은 영웅의 무대라기보다 기다림과 관찰, 그리고 제한적인 개입의 과정에 가깝다.

장애는 영웅의 무대가 아니다

장애 대응에 관한 이야기는 대개 극적인 순간을 중심으로 전해진다. 한 엔지니어가 로그에서 결정적인 단서를 찾고, 남들이 생각하지 못한 명령을 실행해 몇 초 만에 서비스를 되살렸다는 식이다. 이런 사례는 기억에 남지만, 장애 대응의 일반적인 모습을 보여주지는 않는다.

실제로 장애 호출에서 많은 시간은 기다림으로 채워진다. 다른 팀이 원인을 조사하기를 기다리고, 배포가 끝나기를 기다리고, 변경 사항의 결과가 지표에 나타나기를 기다리고, 호출 대상자가 잠에서 깨어나기를 기다린다. 긴장감은 크지만, 매 순간 사람이 실행할 수 있는 일이 많은 것은 아니다.

현대적인 시스템은 스스로 회복하도록 설계되는 경우가 많다. 프로세스가 비정상 종료되면 오케스트레이터가 컨테이너를 재시작한다. 서비스가 과부하로 막히면 클라이언트의 타임아웃과 서킷 브레이커가 요청을 줄인다. 비싼 작업이 일시적으로 몰리면 큐가 요청을 흡수해 시스템 전체가 즉시 무너지지 않도록 한다.

Goedecke는 자신의 장애 호출 경험에서 절반이 넘는 장애가 사람의 개입 없이도 비슷한 시간 안에 회복됐다고 말한다. 이는 모든 장애를 방치해야 한다는 뜻이 아니다. 사람이 해결한 사건과 사람이 성급하게 건드리지 않았더라면 해결됐을 사건을 구분해야 한다는 뜻이다.

성급한 해결이 2차 장애를 만든다

장애가 발생하면 엔지니어는 무언가를 해야 한다는 압박을 느낀다. 모니터링 화면에 큐가 쌓여 있으면 큐를 비우고 싶어진다. 특정 지표가 이상해 보이면 재배포하고 싶어진다. 이런 행동은 적극적으로 보이지만, 시스템의 상태와 작업의 의미를 충분히 파악하지 않은 채 실행하면 원래 문제보다 더 큰 손상을 만든다.

예를 들어 큐 지연이 커졌다는 이유로 큐를 강제로 비우면, 아직 처리되지 않은 중요한 결제 작업까지 사라질 수 있다. 자동 재시도되지 않는 작업이었다면 일시적인 지연 문제가 데이터 손실이나 정산 문제로 바뀐다. 이상한 지표를 보고 여러 번 재배포하면, 원인을 해결하기는커녕 동시에 진행되는 배포가 시스템에 추가 부하를 준다.

장애 중에는 다음과 같은 질문을 먼저 해야 한다.

  • 지금 관찰한 현상은 실제 고장인가, 아니면 회복 과정에서 나타난 일시적인 신호인가?
  • 내가 하려는 조치는 어떤 상태를 지우거나 되돌릴 수 없게 만드는가?
  • 이 조치가 실패하면 원래 장애 외에 어떤 문제가 추가되는가?
  • 자동 복구나 진행 중인 배포가 결과를 보여줄 때까지 기다릴 수 있는가?

이 질문의 목적은 행동을 늦추는 데 있지 않다. 행동의 결과를 예측할 수 없는 상태에서 시스템에 더 많은 변화를 주지 않는 데 있다. 그래서 저자는 장애에서 가장 먼저 할 일이 아무것도 하지 않는 것이라고 말한다.

기다림을 위한 의식이 필요하다

장애 중에 멈추는 일은 기술보다 심리적으로 어렵다. 호출에 들어간 순간부터 무언가를 제안해야 할 것 같고, 아무 명령도 실행하지 않으면 기여하지 않는 사람처럼 느껴진다. 특히 밤중에 호출을 받은 상황에서는 피로와 불안이 판단을 더 빠르게 만든다.

Goedecke는 예전에는 장애 호출에 들어가기 전에 술 한 잔을 따르는 습관이 있었다고 회고한다. 핵심은 술이 아니라, 서두르지 않기 위한 의식을 만드는 데 있었다. 차를 만들거나 집 안을 한 바퀴 걷는 것처럼 건강한 방식으로도 같은 효과를 얻을 수 있다.

팀 차원에서는 이 멈춤을 절차로 만들 수 있다. 호출 시작 시각, 현재 영향 범위, 자동 복구가 진행 중인지, 마지막으로 변경된 요소가 무엇인지 먼저 기록한다. 그리고 새 조치를 실행하기 전에 관찰할 시간과 중단 조건을 합의한다. 이렇게 하면 침묵과 기다림이 무능함이 아니라 의도적인 대응 단계가 된다.

효과적인 조치는 대개 단순하고 지루하다

장애가 자동으로 회복되지 않는다면 필요한 조치는 의외로 복잡하지 않은 경우가 많다. 문제가 되는 기능을 잠시 끄고, 최근 변경을 되돌리고, 트래픽을 줄이고, 시스템이 회복할 때까지 비용이 큰 작업을 중단한다. 충분히 운이 좋으면 문제가 되는 경로에 캐시를 추가하는 정도의 작은 변경으로 끝난다.

코드 수정 자체는 몇 분이면 끝나도 리뷰, CI, 배포를 기다리는 데 한 시간이 걸릴 수 있다. 장애 대응의 성과는 멋진 알고리즘보다 다음과 같은 운영 장치에 의해 좌우된다.

  • 기능 플래그를 빠르게 비활성화할 수 있는가
  • 마지막 변경을 안전하게 롤백할 수 있는가
  • 트래픽이나 작업량을 단계적으로 줄일 수 있는가
  • 중요한 작업과 버려도 되는 작업을 구분할 수 있는가
  • 조치가 효과가 없을 때 원래 상태로 돌아갈 수 있는가

여기서 중요한 기준은 복잡성이 아니라 가역성이다. 장애 중에는 완벽한 수정안을 만드는 것보다, 영향 범위를 줄이고 회복 시간을 확보하는 편이 낫다. 근본 원인 분석과 영구적인 수정은 시스템이 안정된 뒤에 이어갈 수 있지만, 되돌릴 수 없는 조치는 짧은 판단 실수도 오래 남긴다.

장애 대응에는 시스템 맥락 지식이 필요하다

장애 호출에 실력 있는 엔지니어 다섯 명이 모여도 해결하지 못할 수 있다. 반대로 코드베이스와 운영 환경을 오랫동안 다룬 한 사람이 들어와 즉시 적절한 기능 플래그를 끄거나 되돌릴 변경을 알아볼 수도 있다.

이는 그 한 사람이 더 똑똑해서만은 아니다. 장애를 해결하는 행동이 대개 단순하기 때문이다. 어떤 기능이 최근에 켜졌는지, 어느 큐가 중요한 작업을 담고 있는지, 어떤 서비스가 자동 재시도를 하지 않는지, 어떤 설정이 트래픽을 우회시키는지를 아는 것이 핵심이다. 일반적인 디버깅 능력보다 특정 시스템에 대한 지식이 직접적인 해결책으로 연결된다.

따라서 온콜을 여러 사람에게 순환시키는 것만으로는 충분하지 않다. 시스템의 동작을 설명하는 문서, 장애 당시의 대시보드와 로그, 과거 변경의 이유, 안전한 롤백 방법이 함께 축적되어야 한다. 장애를 겪은 사람의 머릿속에만 남은 지식은 다음 호출에서 사용할 수 없다.

합의보다 단호한 책임이 필요한 순간

장애 호출에서는 사람들이 합의를 찾느라 행동을 늦추기 쉽다. “이렇게 해도 괜찮을까요?”, “다른 의견이 있나요?”, “이 조치에 모두 동의하나요?”와 같은 질문을 반복하며 책임을 나눈다. 평상시에는 협업에 도움이 되지만, 장애 중에는 누구도 결정을 내리지 않는 상태가 될 수 있다.

시스템을 잘 아는 사람이 있다면 그 사람은 자신의 판단을 명확하게 말하고 실행해야 한다. “기능 플래그를 끄겠다”고 선언하고, 짧은 관찰 시간을 둔 뒤 실행한다. 이는 독단적으로 행동하라는 뜻이 아니다. 조치의 책임자와 다음 관찰 시점을 분명히 해 팀이 같은 상태를 바라보게 하라는 뜻이다.

장애 대응에서 리더의 역할도 평상시와 다를 수 있다. 기술적인 세부 사항을 모두 이해하지 못하더라도, 실행 책임자가 분명한 결정을 내렸을 때 “지금 실행하라”고 승인해 주는 사람이 필요하다. 중요한 것은 직급이 아니라, 판단을 실행으로 옮길 수 있는 구조다.

장애를 해결하는 능력과 장기적인 영향력은 다르다

장애를 해결하면 조직의 감사와 신뢰를 얻는다. 비기술적인 리더는 평소에는 제품 방향, 일정, 우선순위에 관해 많은 결정을 내리지만, 활성 장애가 발생한 순간에는 기술 시스템을 직접 통제하기 어렵다. 결국 기술팀이 상황을 안정시켜 주기를 기다려야 한다.

그래서 기능 플래그를 끄는 것처럼 단순한 조치도 큰 고마움으로 돌아올 수 있다. 다만 장애를 계속 해결한다고 해서 그 자체로 지속적인 영향력이 보장되지는 않는다. 장애 대응은 기술적으로 불투명하기 때문에 리더가 그 사람이 영웅적인 판단을 했는지, 이미 정해진 절차를 수행했는지 구분하기 어렵다.

더 근본적인 문제는 장애가 발생하지 않는 편이 항상 더 좋은 결과라는 데 있다. 장애를 해결한 성공은 가시적이지만, 장애를 예방한 작업은 사건 자체가 나타나지 않아 드러나지 않는다. 따라서 개인의 인정만을 위해 장애 대응의 영웅성을 키우기보다, 자동 복구와 예방적 설계를 조직의 성과로 기록해야 한다.

시스템 규모에 따라 경험은 달라질 수 있다

원문에는 독자의 반론을 반영한 짧은 수정도 있다. 규모가 작은 회사에서 일한 사람들은 장애가 저절로 사라지는 경우가 드물다고 느낄 수 있다. 저자는 자신이 경험한 대규모 기술 기업의 시스템에는 여러 외부 의존성과 자동화된 복구 장치가 있어, 문제가 스스로 회복되는 일이 더 흔했을 수 있다고 덧붙인다.

이 차이는 중요한 맥락을 제공한다. “기다리면 된다”는 원칙을 모든 시스템에 기계적으로 적용해서는 안 된다. 자동 복구가 실제로 작동하는지, 데이터 손실을 막는 장치가 있는지, 장애가 어느 시점부터 사람의 개입을 필요로 하는지 시스템별로 확인해야 한다.

결국 기다림은 낙관이 아니라 관찰 가능한 가정이어야 한다. 자동 복구 신호가 없거나 영향 범위가 커지고 있다면 즉시 다음 조치로 넘어간다. 반대로 복구 메커니즘이 작동 중이고 조치의 부작용이 크다면, 관찰을 유지하는 편이 더 안전하다.

결론 및 시사점

한 줄 결론: 장애 대응의 핵심은 가장 빨리 무언가를 하는 데 있지 않고, 시스템을 악화시키지 않으면서 필요한 순간에 단순하고 되돌릴 수 있는 조치를 단호하게 실행하는 데 있다.

Sean Goedecke의 글이 주는 교훈은 장애를 가볍게 여기라는 뜻이 아니다. 장애는 스트레스가 크고, 영향 범위가 넓으며, 사람을 서두르게 만든다. 그렇기 때문에 대응의 첫 단계에서 침착함과 관찰을 의도적으로 확보해야 한다.

좋은 장애 대응자는 항상 새로운 명령을 찾는 사람이 아니다. 자동 복구가 진행되고 있는지 판단하고, 성급한 조치가 만들 2차 피해를 계산하고, 시스템의 맥락을 바탕으로 가장 작은 해결 행동을 선택하는 사람이다. 이를 가능하게 만드는 것은 개인의 용기만이 아니라 기능 플래그, 롤백, 관찰 가능한 지표, 운영 문서처럼 평소에 준비한 시스템이다.

장애가 발생하지 않는 것이 최선이지만, 장애를 완전히 없앨 수는 없다. 대신 팀은 장애가 발생했을 때 무엇을 기다리고, 언제 개입하며, 누가 어떤 근거로 결정할지 미리 설계할 수 있다. 그 설계가 되어 있다면 장애 호출은 영웅을 기다리는 자리가 아니라, 시스템의 회복력을 확인하고 필요한 최소 행동을 실행하는 자리가 된다.