서버 성능 저하 발생 시 대처 방법: 문제 진단 입문 가이드
서버가 갑자기 느려지거나 사용자가 응답 시간 초과를 겪고 있다면, 가장 먼저 시스템 상태를 확인해야 한다. 이 문서에서는 서버 성능 문제를 체계적으로排查하는 절차를 설명한다.
전체 부하 확인
서버에 접속한 후 가장 먼저 시스템의 전반적인 부하 상태를 확인한다.
uptime
출력 예시:
14:30:25 up 45 days, load average: 8.52, 6.31, 4.12
맨 뒤 세 개의 숫자는 각각 지난 1분, 5분, 15분간의 평균 부하를 나타낸다. 이 수치가 높은지 판단하려면 먼저 CPU 코어 수를 확인해야 한다.
nproc
예를 들어 4코어 시스템에서 load average가 8을 초과하면 과부하 상태로 볼 수 있다. 일반적으로 부하가 코어 수의 2배를 초과하면 주의가 필요하다.
병목 지점 식별
서버가 느려지는 원인은 다양하다. CPU 처리 능력 부족, 메모리 부족, 디스크 입출력 병목, 네트워크 문제 등을 생각할 수 있다. top 명령어로 현재 시스템 상태를 확인한다.
top
주요 확인 항목:
%Cpu(s): 75.2 us, 12.3 sy, 0.0 ni, 8.5 id, 3.2 wa
각 필드의 의미는 다음과 같다:
- us - 사용자 프로그램이 CPU를 사용 중인 비율. 높으면 애플리케이션이 정상적으로 동작 중
- sy - 시스템 커널이 CPU를 사용 중인 비율. 높으면频繁한 입출력 작업 발생 가능
- id - 유휴 상태. 0에 가까우면 CPU가 바쁨
- wa - 디스크 입출력 대기 시간. 높으면 디스크 처리 속도가跟不上
간단한 판단 기준:
- us와 sy의 합이 100%에 가깝고 id가 0에 가까우면 → CPU 병목
- wa가 20%를 초과하면 → 디스크 입출력 병목
- 위 수치는 정상인데 부하만 높다면 → 네트워크 또는 외부 자원 대기 가능성
CPU 사용률이 높을 때
가장 먼저 어떤 프로세스가 CPU를 많이 사용하는지 확인한다.
# CPU 사용률 순으로 프로세스 확인
ps aux --sort=-%cpu | head -10
# 특정 프로세스의 상세 정보 확인
top
문제를 일으키는 프로세스를 찾았으면 해당 프로세스가 무엇을 하고 있는지 분석한다.
# 자바 프로세스의 경우 스레드 덤프 확인
jstack 프로세스PID
# 일반적인 프로세스 추적
strace -p 프로세스PID
일반적으로 발생하는 원인:
- 무한 루프
- 비효율적인 알고리즘
- 동시 요청 과다 발생
메모리 부족 상황
현재 메모리 사용 현황을 확인한다.
free -h
출력 예시:
total used free shared buff/cache available
Mem: 7.6Gi 5.8Gi 234Mi 123Mi 1.6Gi 1.4Gi
Swap: 2.0Gi 1.0Gi 1.0Gi
重点 확인 항목:
- available - 실제로 사용 가능한 메모리
- Swap used - 0이 아니면 물리 메모리가 부족하여 스왑 사용 중
메모리를 많이 사용하는 프로세스 식별:
ps aux --sort=-%mem | head -10
자바 애플리케이션이 많은 메모리를 사용한다면 힙 크기 조정이 필요하거나 메모리 누수 가능성을 검토해야 한다.
디스크 공간 및 입출력 문제
디스크 사용량 확인:
df -h
사용률이 90%를 초과하면 즉시 정리 작업이 필요하다. 대용량 파일 찾기:
du -sh /* | sort -rh | head -10
입출력 상태 확인:
iostat -x 2
%util 컬럼이 100%에 가까우면 디스크가 바쁜 상태다. 입출력 병목 프로세스 찾기:
iotop -o
실제 사례
증상: 새벽에 API 응답이 갑자기 느려지더니 top 명령어로 확인한 wa(입출력 대기) 값이 40%까지 상승
조사 과정:
# 1. 입출력 문제 확인
iostat -x 2
# %util이 100%에 가까운 값 기록
# 2. 디스크 공간 확인
df -h
# 루트 파티션 사용률 99%!
# 3. 대용량 디렉터리 탐색
du -sh /var/* | sort -rh
# /var/log 디렉터리가 80GB 점유
# 4. 구체적인 로그 파일 확인
ls -lh /var/log/*.log
# 특정 애플리케이션 로그 파일이 60GB 크기
해결 방안:
# 로그 파일 내용만 비우기(파일은 유지)
: > /var/log/xxx.log
# 로그 로테이션 설정으로 재발 방지
디스크 공간을 확보하자마자 서비스가 정상으로 복구되었다.
종합 확인 스크립트
필자는日常적으로 사용하는 종합 체크 스크립트:
#!/bin/bash
echo "===== 시스템 부하 ====="
uptime
echo "===== CPU 및 메모리 요약 ====="
top -bn1 | head -5
echo "===== 메모리 상세 ====="
free -h
echo "===== 디스크 사용량 ====="
df -h | grep -v tmpfs
echo "===== CPU 사용 상위 5개 프로세스 ====="
ps aux --sort=-%cpu | head -6
echo "===== 메모리 사용 상위 5개 프로세스 ====="
ps aux --sort=-%mem | head -6
check.sh 파일로 저장해두면 문제 발생 시 한 번에 전체 상태를 파악할 수 있다.
원격 서버 조사
서버가 내부 네트워크에 위치하면 원격 조사가 번거로울 수 있다.笔者가 관리하는 서버들은 각지 분산되어 있어 문제 발생 시 VPN이나 점프 서버를 통해 접속해야 했고, 네트워크 상태가 안 좋으면 SSH 연결이 끊기는 상황도 발생했다. 이를 해결하기 위해 가상 사설 네트워크를 구성하여 어디서든 가상 IP로 직접 SSH 접속이 가능하도록 했다. 긴급 상황 시 외부에서도 신속하게 조사가 가능해졌다.
정리
서버 성능 문제 조사 절차:
- 시스템 부하 확인 (uptime)
- 병목 유형 식별 (top으로 CPU/메모리/입출력 상태 확인)
- 문제 프로세스特定
- 구체적인 원인 분석
- 해결措施 적용
중요 임계값 기억:
- 부하 > CPU 코어 수 × 2 → 과부하 상태
- CPU wa > 20% → 디스크 입출력 병목
- 디스크 사용률 > 90% → 즉시 정리 필요
연습을重ね하시면 빠르게 대응할 수 있다. 추가 질문이 있으면 논의하자.