← 목록으로

서버 모니터링 분석 가이드

요약
  • 이 기사는 서버 모니터링 그래프를 읽고 분석하는 가이드로, 구글 SRE의 네 가지 황금 신호(트래픽, 지연 시간, 에러, 포화도)를 중심으로 증상과 원인을 파악하는 방법을 설명합니다.
  • 특히 평균 응답 시간 대신 백분위수(P99)를 활용해 장애를 예측하고, CPU와 메모리 등의 리소스 지표를 올바르게 진단하는 실전 분석법을 다룹니다.
  • 대시보드 설치 가이드는 많지만 그래프를 실제로 읽고 진단하는 방법에 대한 가이드는 드물다는 문제의식에서 모니터링을 어떻게 읽고 행동할지 정리한 글
  • 수많은 그래프는 구글 SRE의 네 가지 황금 신호(트래픽·지연 시간·에러·포화도)로 묶이며, 증상(지연·에러)을 먼저 파악하고 원인(CPU·메모리·풀)으로 범인을 좁히는 순서가 분석의 기본임
  • 리소스 지표는 혼자 읽으면 거짓말을 함. CPU 90%여도 응답이 빠르면 당장 문제가 아니고, 20%여도 응답이 느리면 문제임
  • 평균 응답 시간은 분포의 모양을 지우므로 백분위수(P50/P95/P99) 로 읽어야 하며, 장애의 전조는 거의 항상 P99에 먼저 나타남
  • 정상 패턴과 이상 패턴을 애니메이션으로 비교하며 설명하는 구성으로 평시·장애 중·장애 후 각 시점의 분석법까지 다룸

무엇이 중요한가

  • 어떤 지표든 네 가지 황금 신호 중 하나에 속함: 트래픽(얼마나 들어오는가), 지연 시간(얼마나 걸리는가), 에러(얼마나 실패하는가), 포화도(얼마나 차 있는가)
  • 지연 시간과 에러율은 사용자가 실제로 겪는 증상이라 늘어나면 무조건 문제이고, CPU·메모리·스레드 풀 같은 리소스 지표는 원인 쪽임
  • 알람도 원칙적으로 증상에 걸어야 함. "CPU 80% 초과" 알람은 새벽에 사람을 깨우고 아무 일 아닌 경우가 많지만, "에러율 초과" 알람은 누군가 실제로 문제를 겪고 있다는 뜻임

사용자의 문제를 읽는 법

  • 트래픽: 이상 패턴보다 평소 모양부터 외워야 함. 평소를 모르면 이상함도 알아볼 수 없음
    • 수직 하락은 서버가 한가해진 것이 아니라 요청이 도달하지 못하는 것(LB·DNS·게이트웨이)이며, 장애 중에 서버 지표가 전부 깨끗하다면 그것이 가장 큰 이상 신호임
    • 새벽마다 규칙적으로 솟는 스파이크는 대부분 배치나 크론임
    • 트래픽은 분모이기도 함. 같은 에러 500건이라도 분당 요청 백만 건일 때와 천 건일 때는 심각도가 완전히 다르므로 개수는 반드시 비율로 읽어야 함
  • 지연 시간: 평균은 분포의 모양을 지워버림. 전부 100ms인 서버와 대부분 30ms에 일부가 900ms인 서버의 평균은 똑같이 100ms일 수 있음
    • 초당 1,000건이면 매초 10명이 P99를 맞고, 화면 하나에 API를 40번 호출하면 전부 꼬리를 피할 확률은 67%라 사용자 셋 중 하나는 꼬리 지연을 경험함
    • 꼬리에 걸리는 사용자는 무작위가 아님. 데이터가 많은 헤비 유저일수록 무거운 쿼리를 만들므로, P99는 최우수 고객이 겪는 응답 시간일 가능성이 높음
  • 에러: 첫 질문은 "몇 퍼센트인가"가 아니라 "어떤 에러인가"임
    • 5xx는 언제나 우리 문제고, 배포 직후의 4xx 급증은 우리가 API 계약을 깨뜨렸을 가능성이 높음
    • 에러율과 P99가 함께 오르면 어딘가 느려지며 죽는 것이고, 에러율만 치솟고 P99가 멀쩡하면 무언가 즉시 실패 중인 것임
    • 즉시 실패한 요청이 지연 분포에서 빠지면서 장애가 심해질수록 P99가 오히려 좋아 보이는 생존자 편향도 있음

범인을 좁히는 법

  • CPU: CPU 20~30%로 한가한데 응답이 폭증하면 스레드들이 계산이 아니라 무언가(느린 DB, 락, 고갈된 풀, 외부 API)를 기다리는 중임
    • CPU 100% 직선 + 응답 폭증이면 트래픽이 함께 치솟았는지로 용량 문제(스케일 아웃)와 코드 문제(무한 루프)를 구분함
    • 쿠버네티스 CPU limit의 스로틀링은 주기(100ms)당 할당량을 다 쓰면 통째로 멈추는데, 기다린 시간은 사용률 그래프에 남지 않으므로 P99가 튀면 스로틀 지표를 함께 봐야 함
  • 메모리: 톱니 모양은 GC가 일하는 정상 신호(심장 박동)임. 진짜 누수는 봉우리가 아니라 톱니의 바닥(최저점)이 계단처럼 우상향하는 것으로 판별함
    • 누수를 발견하면 그 자리에서 원인을 찾지 말고 힙 덤프를 떠둔 뒤 재시작으로 시간을 버는 것이 옳음
    • 갑작스러운 수직 계단은 전체 조회·엑셀 다운로드류 요청이므로 같은 시각의 액세스 로그와 대조해 범인을 특정함
  • 비둘기집의 원리와 리틀의 법칙: 동시 요청 수 = 초당 유입량 × 평균 처리 시간
    • 처리 시간이 곱해지므로 트래픽이 그대로여도 DB가 2초로 느려지면 동시 요청이 2,000개가 되어 스레드 200개가 순식간에 마름
    • 스레드가 전부 묶이면 헬스 체크도 실패해 LB가 서버를 빼고, 남은 서버가 더 빨리 마르는 연쇄 장애로 이어짐. 죽은 서버부터 살리려 들면 헛수고인 이유임
    • 장애 후 트래픽이 치솟았다면 사용자가 늘어난 것이 아니라 같은 사용자가 여러 번 두드리는 재시도 폭풍으로 읽어야 함
    • 커넥션 풀 고갈 시 반사적으로 풀을 늘리고 싶어지지만, DB가 느려서 마른 것이라면 느린 DB에 줄만 더 길게 세우는 일임. 올바른 질문은 "풀이 작은가"가 아니라 "왜 반납이 느려졌는가" 임
  • 이벤트 루프 서버(Node.js 등): 스레드 풀 사용률 대신 이벤트 루프 지연을 봐야 함
    • 평균이 아니라 최대치나 높은 백분위로, 절대 기준이 아니라 평소 값 대비로 읽어야 함
    • 스케일 단위가 프로세스이므로, 프로세스 8개의 평균 CPU 40% 그래프는 하나가 100%로 죽어가는 상황을 숨김. 집계 단위를 프로세스별로 쪼개야 함

지표 하나로는 보이지 않는 것들

  • 병목: 병목 앞은 대기가 쌓이고 뒤는 한가함. 전체 처리량은 가장 좁은 단이 결정하므로 병목 아닌 곳을 증설해도 소용없음
    • 실전 조합: 전부 느리면 공유 자원(DB·캐시·공용 풀), 특정 API만 느리면 그 API의 코드. 이 판단 하나로 용의선상이 절반으로 줄어듦
    • 대기 시간은 사용률에 비례해 늘지 않음. 50%일 때를 1이라 하면 80%에서 4배, 90%에서 9배, 95%에서 19배로 폭증함. 오토스케일 임계값 80%의 근거이며 "아직 90%니까 10% 남았다"는 계산이 위험한 이유임
  • 큐와 배압: 자라나는 큐는 요청을 구해주는 것이 아니라 전원의 대기 시간을 늘리는 부채임
    • 큐에 상한을 두고 넘치면 429로 즉시 거부하는 로드 셰딩이 모두가 서서히 죽는 것보다 나음
    • 큐 길이 그래프가 우상향을 멈추지 않는다면 흐름 제어가 없거나 부족하다는 뜻임
  • 캐시: 히트율 97%는 DB가 트래픽의 3%만 감당한다는 뜻임. DB 부하가 튀면 DB부터 파지 말고 히트율 급락과 같은 시각인지부터 확인해야 함(캐시 스탬피드)
  • 타임아웃: 게이트웨이 3초, 백엔드 쿼리 5초처럼 조율되지 않으면 백엔드는 성공을 기록하고 게이트웨이는 실패를 기록하는 모순이 생김
    • 안쪽 계층의 타임아웃을 바깥보다 짧게 잡는 타임아웃 예산이 해법임

세 가지 시간

  • 평시 분석: 하루 5분씩 대시보드를 돌며 평소 모양을 눈에 익히는 것
    • 서서히 나빠지는 문제는 알람으로 못 잡으므로, 오늘의 P99 위에 지난주 같은 요일의 P99를 겹쳐 그리는 주간 비교 패널이 유용함
  • 배포 직후 30분이 가장 위험함(장애의 약 70%가 변경에서 비롯됨)
    • 배포 시각을 그래프에 마커로 남기는 것이 비용 대비 효과가 가장 큰 개선임
    • 배포 직후 P99가 두세 배 뛰는 것은 워밍업(JIT, 빈 캐시, 새 커넥션)이라 정상이며, 판단 기준은 값이 아니라 방향임. 우하향하면 지켜보고, 몇 분을 지켜봐도 회복 추세가 없으면 롤백함
    • "에러율 X% 초과 또는 P99가 10분 내 회복 추세 없으면 토론 없이 롤백" 같은 규칙을 팀이 미리 합의해두는 것이 좋음
  • 장애 중: 원인이 아니라 영향 범위부터 확인(트리아지)하고, 최근 30분~몇 시간의 변경을 찾고(변경이 있었다면 범인일 사전 확률이 압도적), 복구를 원인 규명보다 먼저 함
    • 그래프 스무 개를 훑는 대신 "DB가 느려진 거라면 커넥션 대기가 올랐을 것" 같은 가설을 세우고 그래프 하나로 검증함
  • 포스트모템: 첫 흔적·알람·대응 시작·복구의 네 시점을 찍으면 감지의 공백과 대응의 속도라는 두 간격이 보임
    • 산출물은 반성문이 아니라 다음 장애를 짧게 만드는 변경 목록이어야 함
    • 원인은 "슬로 쿼리 때문"에서 멈추지 말고 "실행 계획 확인 절차가 없어서"까지 한 겹 더 들어가야 하며, 원인 칸에 사람 이름을 적으면 다음 장애 때 은폐와 자책을 낳으므로 사람을 탓하지 말아야 함

마치며

  • 모니터링 분석은 외국어 독해와 비슷함. 처음엔 단어(지표)를 사전에서 찾지만 익숙해지면 문장(패턴)이 통째로 읽히고, 나중엔 행간(상관관계)이 보임. 지름길은 없지만 매일 조금씩 읽는 왕도는 있음
  • 알람이 울리면 그래프를 전부 열기 전에 "얼마나 들어오고, 얼마나 걸리고, 얼마나 실패하고, 무엇이 차 있는가"라는 네 가지 질문부터 던질 것
그냥 목록으로
원문 보기 ↗