사수 없이 첫 배포를 앞둔 인턴이 마주치는 낯선 말들
인턴으로 들어온 지 3주 차, 사수가 휴가를 떠나며 작은 배너 문구 수정 배포를 저 혼자 해보라고 맡기고 갔습니다.
에이전트에게 배포 스크립트를 실행해달라고 했더니, 실행 도중에 갑자기 멈추면서 화면에 낯선 메시지가 떴습니다.
배포 스크립트가 스스로 멈춰버릴 때, 킬 스위치의 정체
text
1[ABORTED] error rate 12% exceeded threshold (5%)2Kill switch triggered. Deployment halted.
제가 멈추라고 한 적이 없는데 스스로 멈췄다는 메시지가 떠서 당황했습니다. 화면에 뜬 문구를 그대로 다시 읽어보니 답이 이미 나와 있었습니다.
배포 직후 에러 비율을 자동으로 재고 있다가, 정해둔 기준을 넘으면 사람이 알아채기도 전에 배포 자체를 강제로 멈추는 장치였습니다. 이름 그대로 "죽이는 스위치"라기보다는, 더 큰 사고로 번지기 전에 미리 눌러두는 비상정지 버튼에 가까웠습니다.
스크립트를 고쳐서 다시 배포를 시도했더니, 몇 번이나 실패하다가 결국 성공했습니다. 이상한 건 실패할 때마다 기다리는 시간이 매번 달랐다는 점이었습니다.
재시도할 때마다 기다리는 시간이 길어질 때, 백오프가 하는 일
사수가 예전에 이 프로젝트에 남겨둔 설정 파일을 뒤늦게 열어보다가 이유를 발견했습니다.
json
1{2 "retry": { "strategy": "exponential-backoff", "base": 2 }3}
첫 실패 후엔 2초, 다음엔 4초, 그다음엔 8초, 이런 식으로 재시도 간격이 점점 늘어나도록 미리 짜여 있었습니다. 계속 안 되는 서버에 곧바로 다시 부딪히는 대신, 간격을 벌려가며 서버가 회복할 시간을 벌어주는 방식이었습니다. 문을 계속 두드리는 대신 점점 뜸을 들이며 두드리는 셈입니다.

배포는 됐는데, 정작 스크립트 안에 적힌 경로 하나가 계속 헷갈렸습니다. 같은 실수를 몇 번이나 반복하고 나서야 뭐가 문제인지 알아챘습니다.
같은 이름을 자꾸 다르게 알아들을 때, 레포지토리가 헷갈렸던 이유
사수가 "레포에 올려"라고 메모에 적어둔 걸 보고, 처음엔 그게 서버의 특정 폴더를 말하는 줄 알고 계속 엉뚱한 경로에 파일을 넣었습니다. 같은 실수를 세 번쯤 반복하고서야 뭔가 잘못 이해하고 있다는 걸 깨달았습니다.
레포지토리는 특정 폴더가 아니라, 코드의 변경 이력이 전부 기록된 저장소 자체를 가리키는 말이었습니다. 도서관 서가 하나가 아니라, 그 책의 모든 개정판이 순서대로 보관된 기록보관소 전체를 뜻하는 셈이었습니다. 영어 단어를 소리 나는 대로만 옮겨놓다 보니, 처음 듣는 사람에겐 그게 폴더인지 서버인지 아무 힌트가 없었습니다.
경로 문제를 해결하고 나니, 이번엔 코드를 고치고 나서 결과를 확인하기까지 유독 시간이 오래 걸린다는 걸 알게 됐습니다.
코드를 저장했는데 반영까지 한참 걸릴 때, 컴파일이 필요한 이유
왜 이렇게 오래 걸리는지 궁금해서 검색해봤습니다. 사람이 쓴 코드를 그대로 실행하는 게 아니라, 그 코드를 컴퓨터가 더 빠르게 처리할 수 있는 형태로 미리 변환하는 과정이 중간에 껴 있었습니다.
이 변환 과정을 컴파일, 혹은 빌드라고 불렀습니다. 원고를 쓰고 나서 바로 책이 되는 게 아니라, 편집과 인쇄라는 과정을 거쳐야 서점에 놓이는 것과 비슷합니다. 파일 수가 늘어날수록 이 과정도 길어졌습니다.
변환은 끝났는데, 실제로 서비스를 켰을 때만 나타나는 에러 하나가 계속 로그에 찍혔습니다.
코드 검사는 통과했는데 실제로 켜니 에러가 날 때, 런타임
text
1TypeError: cannot read property 'price' of undefined2 at runtime (checkout.js:42)
로그를 다시 읽어보다가
at runtime이라는 문구가 계속 눈에 밟혔습니다. 컴파일 단계에서는 코드 문법만 검사할 뿐, 실제로 사용자가 그 배너를 클릭하는 그 순간, 데이터가 실제로 들어오는 그 순간에만 벌어지는 오류는 잡아내지 못한다는 걸 알게 됐습니다.레시피에 오타가 없는지 확인하는 것과, 실제로 그 레시피대로 요리해봤을 때 냄비가 너무 작다는 걸 알게 되는 것은 다른 문제입니다. 코드도 마찬가지로, 써놓은 순간과 실제로 돌아가는 순간에 드러나는 문제가 서로 달랐습니다.

배너 문구는 결국 무사히 올라갔습니다. 사수가 돌아와 물어보면 배포에 성공했다는 말보다 중간에 어디서 왜 멈췄는지를 먼저 이야기할 생각입니다. 처음 혼자 해본 배포에서 남은 건 성공이 아니라 그 멈춘 지점들이었습니다.
자주 묻는 질문
킬 스위치 기준값은 누가 정하나요?
보통은 팀에서 서비스 성격에 맞춰 미리 정해둡니다. 기준이 너무 낮으면 사소한 오차에도 배포가 자주 멈추고, 너무 높으면 정작 큰 사고를 놓칠 수 있어서 실제 트래픽 패턴을 보고 조정하는 경우가 많습니다.
백오프 간격은 무한정 늘어나나요?
보통 최대 대기 시간을 정해두고 그 이상은 늘리지 않습니다. 그렇지 않으면 정작 서버가 복구됐는데도 재시도가 너무 늦게 일어나는 역효과가 생기기 때문입니다.
런타임 에러는 컴파일 단계에서 아예 못 잡나요?
일부는 타입 검사 도구로 미리 잡아낼 수 있지만, 실제 사용자 입력이나 외부 서버 응답처럼 실행 시점에만 결정되는 값과 관련된 문제는 결국 실제로 돌려봐야 드러나는 경우가 많습니다.
<a href="/glossary/code-generation" class="glossary-link" title="AI가 자연어 설명이나 기존 코드 문맥을 바탕으로 프로그래밍 코드를 자동으로 작성하는 기술입니다.">AI 코딩</a> 도구 용어 사전 연작의 4편입니다. 다음 편 예고 · 5편 새벽에 신규 기능을 조심스럽게 풀던 스타트업 대표가 만난 말들 카나리 롤아웃 · 콜드스타트 · <a href="/glossary/hallucination" class="glossary-link" title="AI 모델이 통계적 확률에 기반해 다음 단어를 예측하는 과정에서, 사실이 아니거나 근거 없는 정보를 마치 진실인 것처럼 논리적이고 자신감 있게 생성하는 현상입니다.">할루시네이션</a> · 패키지 매니저 · 락파일