지난 포스팅에서는 메모리 누수(OOM)가 발생했을 때 서버를 부검하여 원인을 찾는 힙 덤프(Heap Dump)와 MAT 도구에 대해 알아보았습니다. 하지만 훌륭한 시스템 운영자라면 장애가 터진 후 수습하는 것이 아니라, 실시간으로 서비스의 건강 상태를 파악하고 병목을 사전에 차단해야 합니다.
과거에는 JConsole이나 VisualVM 같은 도구로 서버 한 대씩 상태를 확인했지만, 수십~수백 대의 서버가 얽혀 있는 현대의 마이크로서비스 아키텍처(MSA)에서는 한계가 명확합니다. 이를 극복하기 위해 엔터프라이즈 환경에서는 24시간 시스템 전체를 통합 감시하는 APM(Application Performance Management) 솔루션을 도입합니다. 이번 글에서는 APM이 제공하는 수많은 그래프 중 개발자가 반드시 읽어낼 줄 알아야 하는 핵심 메트릭(지표) 해석 가이드를 정리해 드립니다.
1. 분산 추적(Distributed Tracing)과 APM의 역할
웹 브라우저에서 버튼을 한 번 클릭했을 뿐인데, 내부적으로는 인증 서버, 주문 서버, 결제 서버, 그리고 여러 대의 데이터베이스를 거쳐 응답이 돌아오게 됩니다. 이렇게 복잡한 흐름 속에서 “도대체 어느 서버의 어느 구간 때문에 응답이 3초나 걸렸는가?”를 찾아내는 기술이 분산 추적(Distributed Tracing)입니다.
오픈소스인 핀포인트(Pinpoint), 스카우터(Scouter)부터 상용 툴인 제니퍼(Jennifer), 데이터독(Datadog), 뉴렐릭(New Relic)에 이르기까지 모든 APM은 각 요청마다 고유한 추적 ID(Trace ID)를 부여하여, 사용자 요청이 어느 서버의 어떤 메서드를 거쳐 DB 쿼리까지 도달했는지 그 호출 스택(Call Stack)과 소요 시간을 타임라인 형태로 시각화해 줍니다.
2. 구글 SRE가 제안하는 4대 핵심 지표 (4 Golden Signals)
APM 대시보드를 처음 띄우면 수십 개의 화려한 차트에 압도되기 쉽습니다. 이때 구글의 사이트 신뢰성 엔지니어링(SRE) 팀에서 제안한 시스템 모니터링의 4가지 황금 지표를 기준으로 차트를 해석하면 병목을 쉽게 짚어낼 수 있습니다.
- 처리량 (Traffic / TPS): 서버가 초당 처리하고 있는 트랜잭션의 수(TPS) 또는 분당 요청 수(RPM)를 의미합니다. 평소 100이던 TPS가 갑자기 10으로 뚝 떨어졌다면, 트래픽 유입 경로(로드 밸런서 등)에 문제가 생겼거나 서버 내부 스레드가 무언가에 막혀(Blocked) 일하지 못하고 있다는 뜻입니다.
- 응답 시간 (Latency): 사용자의 요청을 처리하는 데 걸리는 시간입니다. 평균(Average) 응답 시간의 함정에 빠지지 마세요. 전체 요청의 99%가 0.1초 만에 응답하더라도, 상위 1%의 악성 요청이 5초가 걸린다면 평균은 훌륭해 보이지만 특정 사용자는 심각한 지연을 겪고 있는 것입니다. 따라서 상위 95%, 99%의 응답 시간을 나타내는 p95, p99 지표를 중점적으로 확인해야 합니다.
- 에러율 (Errors): 전체 요청 중 HTTP 500(서버 내부 에러) 상태 코드나 Exception이 발생한 비율입니다. 에러율이 갑자기 치솟는 구간의 로그를 APM과 연동하여 즉각 확인해야 합니다.
- 포화도 (Saturation): 시스템의 자원이 얼마나 가득 차 있는지를 나타냅니다. CPU 사용률, JVM 힙 메모리 사용량, 그리고 가장 중요한 데이터베이스 커넥션 풀(DB Connection Pool)의 사용률을 확인하여 리소스 증설(Scale-out) 시점을 결정합니다.
3. 흩뿌려진 점들의 의미: 스캐터 차트(Scatter Chart) 해석법
국내에서 널리 쓰이는 핀포인트(Pinpoint)나 스카우터(Scouter의 X-Log) APM의 가장 큰 특징은 점들이 흩뿌려진 형태의 ‘스캐터 차트’를 제공한다는 점입니다.
가로축은 ‘시간’, 세로축은 ‘응답 속도(Latency)’를 나타내며, 사용자 요청 하나하나가 하나의 점으로 찍힙니다.
- 정상 상태: 대부분의 점들이 세로축 아래쪽(0.1초~0.5초) 구간에 띠를 두르며 밀집해 있습니다.
- 특정 API 병목: 일부 점들이 세로축 위쪽(3초~5초 이상)으로 튀어 올라가 띠를 형성한다면, 무거운 DB 쿼리나 외부 API 통신 지연을 의심해야 합니다. 튀어 올라간 점을 마우스로 드래그하면 해당 요청의 상세 트랜잭션 프로파일을 열어 원인을 0.01초 단위로 분석할 수 있습니다.
- 서버 마비 징후 (수직선 발생): 점들이 특정 시간대에서 일직선으로 위를 향해 치솟는다면(수직선 형태), 서버의 스레드 풀이나 커넥션 풀이 고갈되어 대기 상태(Hang)에 빠졌거나, Full GC가 발생하여 Stop-The-World가 걸렸다는 치명적인 징후입니다.
결론: APM은 비행기의 계기판이다
APM 없이 엔터프라이즈 서버를 운영하는 것은 속도계와 고도계 없이 비행기를 조종하는 것과 같이 무모한 짓입니다. 4대 핵심 지표(Traffic, Latency, Errors, Saturation)를 기준으로 대시보드를 구성하고, 임계치를 넘었을 때 슬랙(Slack)이나 이메일로 알람이 오도록 구성하는 것이 현대 서버 운영의 기본입니다.
애플리케이션 계층의 모니터링을 마스터했으니, 다음 포스팅에서는 애플리케이션을 감싸고 있는 인프라의 관점으로 내려가 보겠습니다. ‘리눅스 환경에서 Java 프로세스의 시스템 리소스(CPU, Memory) 추적 방법’에 대해 리눅스 명령어 위주로 실전 가이드를 다루겠습니다.