서비스를 운영하다 보면 느닷없이 서버가 멈칫거리거나 웹 응답 속도가 현저히 느려지는 장애 상황을 맞닥뜨리게 됩니다.
이때 무작정 서버를 재부팅하기보다는 현상을 정확히 파악하는 것이 중요합니다. CLI 터미널 환경에서 기본으로 탑재되었거나 쉽게 사용할 수 있는 3가지 모니터링 명령어(top, htop, vmstat)를 활용해 서버 과부하의 근본 원인을 원인별로 진단하고 추적하는 방법을 안내해 드립니다.
1. Load Average(부하 평균) 해석법: 리눅스 서버 CPU 부하의 진실
터미널에 top이나 uptime을 치면 화면 상단에 가장 먼저 눈에 띄는 숫자가 바로 Load Average입니다.
흔히 이 값을 ‘CPU 사용률’로 착각하곤 하지만, 실상은 ‘CPU 자원을 얻기 위해 대기 중이거나 작업 중인 프로세스의 평균 수’를 의미합니다.
- 세 개의 숫자 의미: load average: 2.15, 1.80, 1.05처럼 나열된 수치는 순서대로 최근 1분, 5분, 15분간의 평균 부하를 뜻합니다. 1분 수치가 15분 수치보다 확연히 높다면 현재 부하가 급격히 치솟고 있는 상황입니다.
- 코어 수와의 비교가 핵심: 시스템의 CPU 코어 개수(nproc 명령어로 확인)가 기준점이 됩니다.
- 4코어 서버에서 Load Average가 4.0이라면, 4개의 코어가 쉬지 않고 100% 일하고 있는 최적 상태입니다.
- 만약 4코어 서버에서 수치가 8.0 이상을 넘어선다면, 프로세스들이 자기 차례를 기다리며 심각한 줄 서기(병목)를 겪고 있다는 신호입니다.
Tip: CPU 사용률은 낮은데 이상하게 Load Average만 하늘을 찌른다면? 이는 CPU 문제가 아니라 뒤에서 설명할 디스크 I/O 병목일 확률이 매우 높습니다.
2. top과 htop으로 자원 먹는 리눅스 서버 귀신 프로세스 잡기
장애가 터졌을 때 실시간 상태를 가장 직관적으로 보여주는 도구입니다.
top 명령어 기본 활용법
- top 실행 후 대문자 P를 누르면 CPU 사용량이 가장 높은 프로세스 순으로, 대문자 M을 누르면 메모리(RAM) 점유율이 높은 순으로 정렬됩니다.
- %Cpu(s) 줄을 유심히 보셔야 합니다.
- us (user): 일반 애플리케이션(Node.js, Java, Python 등)이 쓰는 CPU 비중
- sy (system): 리눅스 커널 내부 처리에 소비되는 CPU 비중
- wa (iowait): 디스크 입출력을 기다리며 허송세월하는 CPU 시간 비중
시각적이고 직관적인 htop
htop은 기본 top에 화려한 컬러 그래프와 인터랙티브 기능을 얹은 도구입니다 (sudo apt install htop 등으로 설치).
- 각 코어별 사용량이 막대그래프로 나타나 특정 코어 하나만 100%를 찍는 ‘단일 쓰레드 병목’ 현상을 한눈에 파악할 수 있습니다.
- F3(검색), F4(필터) 키로 특정 프로세스를 찾거나, 방향키로 프로세스를 선택한 뒤 F9(Kill)로 즉시 문제가 되는 프로세스를 종료시킬 수도 있습니다.
3. 리눅스 서버 메모리 스왑(Swap) 발생 시 대처법
서버에 물리 메모리(RAM)가 부족해지면, 리눅스 커널은 디스크의 일부 공간을 메모리처럼 임시로 쓰는 스왑(Swap) 메모리를 활성화합니다.
하지만 SSD나 HDD 같은 저장 장치는 실제 RAM보다 읽기/쓰기 속도가 수백 배 이상 느립니다. 따라서 스왑이 활발하게 일어나는 순간 서버 성능은 바닥으로 떨어집니다.
- 증상 확인: free -h나 top 화면에서 Swap: used 수치가 계속 올라가고 있다면 메모리가 고갈된 상태입니다.
- vmstat으로 스왑 동작 주기 파악:
Bash
vmstat 1
명령어를 입력하면 1초 간격으로 서버 상태가 출력됩니다. 여기서 memory 항목의 si (swap-in)와 so (swap-out) 수치를 확인해야 합니다.
- si와 so 숫자가 continuous하게 0보다 큰 값으로 계속 움직인다면, 메모리가 부족해 디스크와 메모리를 미친 듯이 오가는 ‘스래싱(Thrashing)’ 현상이 일어나는 중입니다.
- 대처법:
- 가장 먼저 메모리를 과도하게 점유 중인 프로세스(Java 힙 메모리 설정 과다, DB 인메모리 캐시 폭증 등)를 찾아 옵션을 조정하거나 프로세스를 재시작합니다.
- 임시방편으로 필요 없는 캐시 메모리를 비워줄 수 있습니다 (sysctl -w vm.drop_caches=3).
- 근본적인 해결을 위해서는 물리 RAM 스펙을 상향(Scale-up)하거나 애플리케이션의 메모리 누수(Leak)를 잡아야 합니다.
4. I/O Wait에 따른 디스크 병목 현상 진단
“CPU 사용률은 10%밖에 안 되는데 웹 서비스가 완전히 굳어버렸다” 할 때 범인은 열에 아홉 디스크 I/O 병목입니다.
- 진단법: vmstat 1 실행 후 cpu 섹션의 wa (iowait) 값과 procs 섹션의 b (blocked) 값을 살핍니다.
- wa 비율이 20~30% 이상으로 높고, b (디스크 입출력을 대기하며 D-state 멈춤 상태에 빠진 프로세스 수)의 숫자가 1 이상 지속된다면 디스크가 수용량을 초과한 것입니다.
- 원인 추적: 어떤 프로세스가 디스크를 갉아먹고 있는지 보려면 iotop 명령어를 설치하여 투입해 보는 것이 가장 효과적입니다.
- 주요 원인 예시:
- 갑작스러운 접근 폭주로 웹 서버의 로그 파일(Access Log)이 과도하게 쓰이는 경우
- 데이터베이스(MySQL 등)에서 인덱스 없이 풀 스캔(Full Table Scan) 쿼리가 돈 경우
- Cron 작업 등으로 대용량 백업/압축 파일 처리가 진행 중인 경우
서버에 문제가 생겼을 때는 당황하지 말고 top이나 htop으로 전체적인 그림을 먼저 그린 후, vmstat 1을 통해 CPU 병목인지, 메모리 고갈(스왑)인지, 디스크 I/O 병목인지 3가지 중 하나로 범위를 좁혀나가는 것이 원인 추적의 정석입니다.
원인을 정확히 파악하면 불필요한 서버 증설 비용을 아끼고 장애를 신속하게 해결할 수 있습니다. 운영 중인 서버에서 미리 각 명령어들을 입력해 보며 정상 상태의 수치 감각을 익혀두시는 것을 추천합니다.