"서버 다운됐네, 나중에 다시 해": 사이트가 죽었을 때 실제로 어떤 일이 벌어지고 있는가
요약
서버 다운 현상이 발생하는 구체적인 기술적 원인을 관측성(Observability) 도구인 SigNoz를 통해 분석합니다. 데이터베이스 쿼리 지연과 같은 실제 장애 사례를 시뮬레이션하며, 단순한 대시보드 확인을 넘어 알림(Alert)의 중요성을 강조합니다.
핵심 포인트
- 서버 다운은 단순한 현상이 아니라 다양한 기술적 원인의 결과임
- SigNoz를 활용해 데이터베이스 지연 등 장애 상황을 시각화 가능
- 대시보드는 수동적이지만, 알림(Alert)은 능동적인 장애 대응을 가능케 함
- 트레이스(Trace) 분석을 통해 병목 구간을 구체적으로 식별할 수 있음
잘 지내고 계신가요?
우리가 아주 많이 들어온 상징적인 문구, "서버 다운됐네, 나중에 다시 해(server down, try later)"에 대해 이야기해 봅시다. 여러분의 아버지는 Tatkal 티켓을 예매하려 할 때 이 말을 하셨을 겁니다. 여러분의 사촌은 JEE 결과가 발표되어 포털 사이트가 절망의 회전하는 로딩 바(spinning wheel)로 변했을 때 이 말을 했을 겁니다. 이것은 기술에 대해 어깨를 으쓱하며 넘기는 우리의 국가적인 방식이 되었습니다. 마치 인터넷이 날씨와 같아서, 서버는 그냥... 가끔 다운되는 것이고, 누구의 잘못도 아니며, 불가항력적인 일(act of god)이니, 나중에 다시 하면 된다는 식이죠.
하지만 이것은 날씨가 아닙니다. 사이트가 다운될 때마다 로그(log)나 트레이스(trace) 어딘가에 아주 구체적이고, 찾을 수 있는 이유가 존재합니다. 하지만 그것을 확인하는 것은 귀찮고 "나중에 다시 하기"는 공짜이며 노력이 전혀 들지 않기 때문에 거의 아무도 그것을 보지 않습니다. 그래서 저는 해커톤을 위해 "서버 다운됐네"라고 말하는 것을 멈추고, 실제로 "다운(down)"이 무엇을 의미하는지 알아내기로 했습니다. 저는 가짜 시험 결과 웹사이트를 만들고, 명령에 따라 이를 망가뜨릴 수 있는 권한을 스스로에게 부여한 다음, SigNoz라는 관측성(observability) 도구를 사용하여 "다운"이 내부에서 매번 정확히 어떤 모습인지 지켜보았습니다.
결과적으로 "서버 다운"은 한 가지 현상이 아니었습니다. 그것은 최소한 네 가지의 서로 다른 현상이 같은 트렌치코트를 입고 있는 것과 같았습니다.
용의자 #1: 서두르는 법을 잊어버린 데이터베이스
이것은 지루하면서도 가장 흔한 경우입니다. 여러분의 "결과 확인" 버튼 뒤 어딘가에서 데이터베이스에 질문이 던져지고 있는데, 때때로 그 질문에 답하는 데 걸리는 시간이 지나치게 길어질 때가 있습니다. 너무 많은 사람이 동시에 질문하거나, 잘못 작성된 쿼리(query) 때문일 수도 있습니다. 사이트가 "다운"된 것이 아닙니다. 그저... 기다리고 있는 것입니다. 아주 정중하게, 영원히 말이죠.
저는 백엔드(backend)가 데이터베이스에 접근하기 전에 3초 동안 낮잠을 자도록 명령함으로써 이를 시뮬레이션했습니다:
with tracer.start_as_current_span("db.query") as db_span:
if state.db_slowdown:
db_span.set_attribute("chaos.triggered", "db_slowdown")
...
SigNoz의 트레이스 탐색기(trace explorer)를 열어 지속 시간별로 정렬해 보니, 가장 위에 db.query라고 표시된 크고 눈에 띄는 스팬이 있었습니다. 이 스팬은 폭이 3초였으며, 속성에는 문자 그대로 chaos.triggered: db_slowdown이라고 적혀 있었습니다. 즉,
이것은 SigNoz에서 완전히 다르게 나타납니다. 느린 트레이스 (slow trace)가 아니라, 실패한 트레이스로 나타나며, 만약 에러율 (error-rate) 패널을 보고 있다면 마치 절벽처럼 보입니다. 한순간에는 평평한 0%였다가, 다음 순간에는 10%를 넘어서며 급증합니다. 실제로 저는 정확히 이런 상황을 포착하도록 알림 (alert)을 설정해 두었는데, 제가 이 시나리오를 켜는 순간 아무런 예고 없이 알림이 울렸습니다. 이것이 대시보드 (dashboard)와 알림 (alert)의 차이입니다. 대시보드는 당신이 보기를 기다리지만, 알림은 당신의 어깨를 톡톡 두드립니다.
용의자 #4: 모두가 한꺼번에 몰려드는 경우
그리고 누구의 잘못도 아닌 상황이 있습니다. 결과 발표일, 티켓 예매일, 세일 기간 — 십만 명의 사람들이 동일한 10분 동안 같은 버튼을 클릭하고, 평범한 화요일에 맞춰진 인프라 (infrastructure) 규모는... 감당하지 못합니다. 저는 1분 동안 초당 요청 수 (requests-per-second)를 점진적으로 높이는 작은 스크립트를 작성했는데, 지연 시간 (latency)이 함께 치솟는 동안 SigNoz 자체의 "requests/sec" 패널이 올라가는 것을 지켜보는 것은, 이번 프로젝트를 진행하며 실제 결과 발표일을 목격하는 것과 가장 유사한 경험이었습니다.
이 상황에 대한 솔직한 진실은 이렇습니다. 트래픽 급증 (traffic spikes) 그 자체는 보통 근본 원인이 아닙니다. 그것은 앞서 언급한 세 명의 용의자 중 누가 이미 가장 취약했는지를 드러내는 스트레스 테스트 (stress test)입니다.
Foundry를 사용하여 SigNoz를 설치해 보았는데 꽤 멋졌습니다:
curl -fsSL https://signoz.io/foundry.sh | bash
mkdir signoz-install && cd signoz-install
foundryctl cast -f casting.yaml
만약 당신의 대시보드에 아무것도 나타나지 않는다면, 절반의 경우는 코드 버그 (code bug) 때문이 아닙니다. 당신이 신뢰했던 문서 페이지가 실제 버전보다 뒤처져 있어서, 텔레메트리 (telemetry)가 조용히 아무 곳에도 전송되지 않고 있기 때문입니다. 앱이 문제라고 가정하기 전에 확인해 볼 가치가 있습니다.
시각화가 가능해졌을 때, "나중에 다시 시도"가 실제로 의미하는 것
제가 주말 내내 의도적으로 이 작업을 수행한 후 깨달은 점은 이것입니다. "서버 다운"은 진단이 아니라, 문제를 보지 않으려는 방식이라는 것입니다. 위에서 언급한 네 명의 용의자 각각은 실제 트레이싱 (Tracing)과 메트릭 (Metrics)이 갖춰지는 순간, 완전히 다르고 구체적인 지문(fingerprint)을 남깁니다. 길게 늘어진 스팬 (Span), 평탄해진 캐시 히트율 (Cache-hit rate), 특정 에러 코드의 급증, 혹은 상승하는 RPS 그래프 같은 것들 말이죠. 이 중 그 어떤 것도 추측을 필요로 하지 않습니다. 이들은 문제가 발생한 '도중'이 아니라, 나쁜 날이 오기 '전'에 누군가가 텔레메트리 (Telemetry)를 연결해 두었을 때만 확인할 수 있습니다.
이것이 바로 SigNoz와 같은 관측성 (Observability) 도구들이 내세우는 실제 가치입니다. 영업용 멘트를 빼고 말하자면, 아무도 확인하지 않는 대시보드에서 인상적으로 보이는 것이 목적이 아닙니다. 장애 상황 한복판에서 "데이터베이스 문제입니다"라고 큰 소리로 말할 수 있고, "서버 다운됐네, 나중에 다시 해"라고 말하며 저녁때쯤 저절로 고쳐지길 기도하는 대신, 1분 안에 정확히 맞히는 것이 목적입니다.
요약
다음에 사이트가 다운된다면, 그것은 날씨 때문이 아닙니다. 네 명의 용의자 중 한 명 때문이며, 어딘가에서 누군가는 이를 실시간으로 포착할 수 있는 텔레메트리 (Telemetry)를 가지고 있거나, 혹은 가지고 있지 않을 것입니다. 저는 아주 긴 주말 동안 가짜 시험 결과 포털을 대상으로, 적어도 텔레메트리를 갖춘 사람이 되기로 결심했습니다. 그리고 솔직히 말해서, 느린 트레이스 (Trace)가 실시간으로 밝혀지는 것을 지켜보는 것은 기대 이상으로 만족스러운 경험이었습니다.
저의 해커톤 (Hackathon) 프로젝트:
제 프로젝트는 여러분을 국가 시험 결과 포털의 온콜 (On-call) SRE(Site Reliability Engineer) 입장에 놓이게 합니다. 학생 포털 (Student Portal)에서는 "학생"들이 수험 번호, 생년월일, 캡차 (Captcha)를 통해 결과를 확인할 수 있습니다. 별도의 미션 컨트롤 (Mission Control) 패널은 SRE에게 라이브 백엔드 (Backend)에 실제 운영 환경의 장애를 주입할 수 있는 네 개의 로커 스위치 (Rocker-switch) 토글을 제공합니다:
- 데이터베이스 지연 (Database Latency) — DB 스팬 (Span)에 수 초의 지연을 주입합니다.
- Redis / 캐시 장애 (Cache Failure) — 모든 요청이 Postgres를 직접 통과하도록 강제합니다.
- 배포 버그 (Deployment Bug) — 요청의 약 50%에 대해 무작위로 500 에러를 발생시킵니다.
- 트래픽 급증 (Traffic Spike) — 초당 요청 수를 높이는 부하 생성 (Load-generator) 스크립트와 함께 작동합니다.
스위치를 켜서 포털이 저하되는 것을 지켜본 다음, SigNoz를 열어 정확히 실패하고 있는 스팬 (span)을 찾아내고, 라이브 대시보드 (live dashboard) 및 발생 중인 알람 (alert)과 대조하여 확인한 뒤, 다시 스위치를 끄고 복구되는 과정을 지켜보세요 — 이 모든 것이 실시간으로 이루어집니다.
SigNoz 해커톤 (hackathon)을 위해 제작되었습니다.
Arigato !!!!
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기