⚡ 서버 CPU가 100%인데 도대체 뭐가 문제인지 모르겠다고요? 이 글 하나면 CPU 사용량 분석의 모든 것을 마스터할 수 있어요!
서버 관리를 하다 보면 가장 자주 마주치는 상황이 바로 “CPU 사용률이 갑자기 높아졌는데 원인을 모르겠다”는 것입니다. 시스템이 느려지고, 사용자들이 불만을 토로하기 시작하면 관리자는 빠르게 원인을 찾아야 하죠.
리눅스에서 CPU 사용량 분석은 단순히 숫자를 보는 것이 아니라, 시스템의 성능 상태를 정확히 진단하고 최적화 방향을 찾는 핵심 기술입니다. 이 글을 통해 CPU 사용량 모니터링부터 문제 해결까지 완벽하게 마스터해보세요!
🎯 CPU 사용량이 높아지는 주요 원인들
시스템 부하의 근본적인 이유
CPU 사용량이 비정상적으로 높아지는 상황은 다음과 같은 원인들로 발생합니다:
1. 애플리케이션 레벨 문제
- 무한 루프: 잘못된 로직으로 인한 CPU 점유
- 비효율적인 알고리즘: O(n²) 복잡도의 알고리즘 사용
- 메모리 누수: GC(Garbage Collection) 과도한 실행
- I/O 블로킹: 동기 처리로 인한 스레드 대기
2. 시스템 레벨 문제
- 컨텍스트 스위칭 과다: 너무 많은 프로세스/스레드
- 인터럽트 폭주: 하드웨어 장치 오류
- 커널 모듈 오류: 디바이스 드라이버 문제
- 스왑 스래싱: 메모리 부족으로 인한 과도한 스왑
3. 외부 요인
- DDoS 공격: 네트워크 요청 폭주
- 배치 작업: 크론 작업 중복 실행
- 백업 프로세스: 압축 및 암호화 작업
📊 리눅스 CPU 사용량 모니터링 도구 완전 정복
top 명령어: 실시간 프로세스 모니터링의 왕
# 기본 top 실행
top
# 1초마다 업데이트
top -d 1
# 특정 사용자의 프로세스만 표시
top -u username
# CPU 사용률 기준으로 정렬
top -o %CPU
top 출력 해석하기:
Tasks: 234 total, 2 running, 232 sleeping, 0 stopped, 0 zombie
%Cpu(s): 5.2 us, 2.1 sy, 0.0 ni, 92.1 id, 0.3 wa, 0.0 hi, 0.3 si, 0.0 st
MiB Mem : 7936.2 total, 1245.8 free, 3250.1 used, 3440.3 buff/cache
MiB Swap: 8191.0 total, 8191.0 free, 0.0 used. 4243.2 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1234 apache 20 0 234532 45672 12345 R 85.5 2.3 0:45.67 httpd
5678 mysql 20 0 1234567 567890 89012 S 25.8 12.1 12:34.56 mysqld
CPU 사용률 지표 상세 분석
- us (user): 사용자 공간에서의 CPU 사용률 (일반 애플리케이션)
- sy (system): 시스템 공간에서의 CPU 사용률 (커널, 시스템 콜)
- ni (nice): 우선순위가 조정된 사용자 프로세스의 CPU 사용률
- id (idle): CPU 유휴 시간 (높을수록 여유가 있음)
- wa (wait): I/O 대기 시간 (높으면 디스크/네트워크 병목)
- hi (hardware interrupt): 하드웨어 인터럽트 처리 시간
- si (software interrupt): 소프트웨어 인터럽트 처리 시간
- st (steal): 가상화 환경에서 다른 VM이 CPU를 사용하는 시간
htop: top의 강화된 버전
# htop 설치
sudo yum install epel-release
sudo yum install htop
# 또는 Ubuntu/Debian
sudo apt install htop
# 실행
htop
htop의 고급 기능들:
- 컬러풀한 인터페이스로 직관적 파악
- 마우스 지원으로 클릭 기반 조작
- 프로세스 트리 뷰로 부모-자식 관계 확인
- 실시간 검색 및 필터링
- 시스템 정보 통합 표시
ps 명령어: 정적 프로세스 정보 확인
# CPU 사용률 높은 순으로 정렬
ps aux --sort=-%cpu | head -20
# 특정 사용자의 프로세스만 확인
ps aux --sort=-%cpu | grep apache
# 실행 중인 프로세스만 확인
ps aux --sort=-%cpu | grep -v " 0.0 "
# 상세한 프로세스 정보
ps -eo pid,ppid,%cpu,%mem,cmd --sort=-%cpu | head -20
ps 출력 해석:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
apache 1234 85.2 5.6 234532 45672 ? R 14:23 0:45 /usr/sbin/httpd
mysql 5678 25.8 12.1 1234567 567890 ? S Mar01 12:34 /usr/bin/mysqld
프로세스 상태 코드 (STAT)
- R: 실행 중 (Running)
- S: 인터럽트 가능한 대기 상태 (Sleeping)
- D: 인터럽트 불가능한 대기 상태 (일반적으로 I/O 대기)
- Z: 좀비 프로세스 (부모가 정리하지 않은 종료 프로세스)
- T: 정지된 프로세스 (Stopped)
🔍 고급 CPU 분석 도구들
sar 명령어: 시스템 활동 보고서
# sar 설치 (sysstat 패키지)
sudo yum install sysstat
sudo apt install sysstat
# 현재 CPU 사용률 1초마다 10번 출력
sar -u 1 10
# 오늘 하루 동안의 평균 CPU 사용률
sar -u
# 특정 날짜의 CPU 통계
sar -u -f /var/log/sysstat/saXX
# CPU 코어별 사용률
sar -P ALL 1 5
sar 출력 예시:
14:35:02 CPU %user %nice %system %iowait %steal %idle
14:35:03 all 8.25 0.00 2.13 0.25 0.00 89.37
14:35:03 0 12.50 0.00 3.75 0.50 0.00 83.25
14:35:03 1 4.00 0.00 0.50 0.00 0.00 95.50
pidstat: 프로세스별 상세 통계
# 모든 프로세스의 CPU 사용률
pidstat
# 특정 프로세스 모니터링
pidstat -p 1234
# 1초마다 5번 출력
pidstat 1 5
# CPU 사용률과 함께 명령어도 표시
pidstat -l
# 특정 사용자의 프로세스만
pidstat -U apache
vmstat: 가상 메모리 통계
# 기본 vmstat 실행
vmstat
# 2초마다 10번 출력
vmstat 2 10
# 더 자세한 정보 출력
vmstat -a 2 10
vmstat CPU 관련 컬럼:
- us: 사용자 코드 실행 시간
- sy: 시스템 코드 실행 시간
- id: 유휴 시간
- wa: I/O 대기 시간
⚡ CPU 사용량이 높은 프로세스 실시간 추적
실시간 모니터링 스크립트
#!/bin/bash
# cpu_monitor.sh - CPU 사용량 실시간 모니터링
echo "=== CPU 사용량 TOP 10 프로세스 ==="
while true; do
clear
echo "$(date): CPU 사용량 높은 프로세스들"
echo "----------------------------------------"
# CPU 사용률 상위 10개 프로세스
ps aux --sort=-%cpu | head -11 | tail -10 | \
awk '{printf "PID: %-8s CPU: %-6s MEM: %-6s CMD: %s\n", $2, $3"%", $4"%", $11}'
echo "----------------------------------------"
echo "전체 CPU 사용률:"
top -bn1 | grep "Cpu(s)" | awk '{print "User: "$2" System: "$4" Idle: "$8}'
sleep 5
done
특정 프로세스 CPU 사용 패턴 분석
# Apache 프로세스들의 CPU 사용률 추적
watch -n 2 "ps aux | grep httpd | grep -v grep | sort -k3 -nr"
# MySQL 프로세스 모니터링
watch -n 1 "pidstat -p \$(pgrep mysqld)"
# Java 애플리케이션 모니터링
watch -n 2 "ps aux | grep java | grep -v grep | awk '{print \$2, \$3, \$11}'"
🚨 높은 CPU 사용률 원인 진단법
1. 무한 루프 탐지
# 특정 프로세스의 시스템 콜 추적
strace -p 1234
# 함수 호출 추적
ltrace -p 1234
# 프로세스가 어떤 파일을 열고 있는지 확인
lsof -p 1234
무한 루프 징후:
- 같은 시스템 콜이 계속 반복
- CPU 사용률이 지속적으로 높음
- I/O 활동이 거의 없음
2. 메모리 누수로 인한 GC 과부하
# Java 프로세스의 가비지 컬렉션 모니터링
jstat -gc 1234 5s
# 힙 덤프 분석
jmap -dump:format=b,file=heap.hprof 1234
# Python 프로세스 메모리 사용량
ps -p 1234 -o pid,vsz,rss,comm
3. I/O 대기로 인한 CPU 점유
# I/O 통계 확인
iostat -x 1 5
# 프로세스별 I/O 사용량
iotop
# 디스크 사용률이 높은 프로세스
pidstat -d 1 5
🔧 시스템 레벨 CPU 분석
인터럽트 분석
# 인터럽트 통계 확인
cat /proc/interrupts
# 실시간 인터럽트 모니터링
watch -n 1 "cat /proc/interrupts | head -20"
# 소프트 인터럽트 확인
cat /proc/softirqs
비정상적인 인터럽트 징후:
- 특정 IRQ의 카운트가 급격히 증가
- 네트워크 인터럽트가 과도하게 발생
- 디스크 관련 인터럽트 폭증
컨텍스트 스위칭 분석
# 컨텍스트 스위치 통계
vmstat 1 5
# 프로세스별 컨텍스트 스위치
pidstat -w 1 5
# 시스템 전체 컨텍스트 스위치 추이
sar -w 1 10
컨텍스트 스위칭이 높은 경우:
- 너무 많은 스레드가 동시 실행
- 락(Lock) 경합 상황 발생
- I/O 블로킹이 빈번함
로드 평균(Load Average) 분석
# 현재 로드 평균 확인
uptime
# 상세한 로드 정보
cat /proc/loadavg
# 히스토리컬 로드 평균
sar -q 1 10
로드 평균 해석:
- 1분 로드 < CPU 코어 수: 정상 상태
- 1분 로드 = CPU 코어 수: 완전 사용 상태
- 1분 로드 > CPU 코어 수: 과부하 상태
🎯 실전 CPU 문제 해결 사례
사례 1: 웹서버 CPU 사용률 급상승
상황: Apache 웹서버의 CPU 사용률이 갑자기 90% 이상으로 급상승
진단 과정:
# 1. 전체 시스템 상태 파악
top
# 2. Apache 프로세스들 확인
ps aux | grep httpd | sort -k3 -nr
# 3. Apache 로그 분석
tail -f /var/log/httpd/access_log | grep -E "(POST|GET)" | head -100
# 4. 네트워크 연결 상태 확인
netstat -an | grep :80 | wc -l
# 5. 특정 Apache 프로세스 추적
strace -p 1234
해결 방법:
- 비정상적인 요청 패턴 차단
- Apache 설정 최적화 (MaxRequestWorkers 조정)
- 리버스 프록시 도입으로 부하 분산
사례 2: 데이터베이스 서버 성능 저하
상황: MySQL 서버의 CPU 사용률이 지속적으로 높음
# MySQL 프로세스 목록 확인
mysqladmin processlist
# 느린 쿼리 로그 분석
mysql -e "SHOW PROCESSLIST;"
# MySQL 상태 정보
mysqladmin status
# 시스템 리소스와 MySQL 상관관계
pidstat -p $(pgrep mysqld) 1 10
사례 3: 배치 작업으로 인한 시스템 부하
상황: 크론 작업이 중복 실행되어 시스템 부하 증가
# 실행 중인 크론 작업 확인
ps aux | grep cron
# 크론 로그 확인
tail -f /var/log/cron
# 특정 스크립트가 몇 개 실행 중인지 확인
ps aux | grep backup_script.sh | grep -v grep | wc -l
🛠️ CPU 사용량 최적화 전략
1. 프로세스 우선순위 조정
# 프로세스 우선순위 확인
ps -eo pid,pri,ni,comm | grep process_name
# nice 값으로 우선순위 조정 (낮은 우선순위로)
nice -n 10 ./cpu_intensive_program
# 실행 중인 프로세스 우선순위 변경
renice 10 1234
# 실시간 우선순위 설정 (주의해서 사용)
chrt -f 99 ./real_time_process
2. CPU 친화성(CPU Affinity) 설정
# 현재 프로세스의 CPU 친화성 확인
taskset -p 1234
# 특정 CPU 코어에만 실행하도록 제한
taskset -p 0x1 1234 # CPU 0번에만 실행
taskset -p 0x3 1234 # CPU 0, 1번에만 실행
# 프로그램 실행 시 CPU 친화성 설정
taskset 0x1 ./my_program
3. 시스템 튜닝
# CPU 거버너 확인 및 설정
cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
# 성능 모드로 변경 (최대 성능)
echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
# 절전 모드로 변경 (전력 절약)
echo powersave | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
📈 자동화된 CPU 모니터링 시스템 구축
CPU 임계치 알림 스크립트
#!/bin/bash
# cpu_alert.sh - CPU 사용률 임계치 도달 시 알림
CPU_THRESHOLD=80
EMAIL="admin@example.com"
while true; do
# 현재 CPU 사용률 계산
CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1)
CPU_USAGE_INT=$(echo $CPU_USAGE | cut -d'.' -f1)
if [ "$CPU_USAGE_INT" -gt "$CPU_THRESHOLD" ]; then
# CPU 사용률이 임계치를 넘은 프로세스들 확인
HIGH_CPU_PROCS=$(ps aux --sort=-%cpu | head -6 | tail -5)
# 알림 메일 전송
echo "CPU 사용률이 ${CPU_USAGE}%로 임계치(${CPU_THRESHOLD}%)를 초과했습니다.
CPU 사용률 높은 프로세스들:
$HIGH_CPU_PROCS
서버: $(hostname)
시간: $(date)" | mail -s "CPU 사용률 경고" $EMAIL
# 로그 기록
echo "$(date): CPU 사용률 ${CPU_USAGE}% 경고 발송" >> /var/log/cpu_monitor.log
# 5분간 대기 (중복 알림 방지)
sleep 300
fi
sleep 60
done
성능 데이터 수집 스크립트
#!/bin/bash
# collect_cpu_stats.sh - CPU 성능 데이터 수집
LOG_FILE="/var/log/cpu_performance.log"
DATE=$(date '+%Y-%m-%d %H:%M:%S')
# CPU 사용률 정보
CPU_INFO=$(top -bn1 | grep "Cpu(s)")
# 로드 평균 정보
LOAD_INFO=$(uptime | awk -F'load average:' '{print $2}')
# CPU 사용률 높은 프로세스 TOP 5
TOP_PROCS=$(ps aux --sort=-%cpu | head -6 | tail -5 | awk '{print $2","$3","$11}')
# 로그 파일에 기록
echo "$DATE,$CPU_INFO,$LOAD_INFO" >> $LOG_FILE
echo "$DATE,TOP_PROCESSES,$TOP_PROCS" >> $LOG_FILE
# 일주일 이상 된 로그 파일 정리
find /var/log -name "cpu_performance.log.*" -mtime +7 -delete
🔍 고급 CPU 분석 도구들
perf: Linux 성능 분석 도구
# perf 설치
sudo yum install perf
sudo apt install linux-perf
# 시스템 전체 CPU 프로파일링
sudo perf top
# 특정 프로세스 프로파일링
sudo perf top -p 1234
# CPU 이벤트 기록 및 분석
sudo perf record -g ./my_program
sudo perf report
strace: 시스템 콜 추적
# 프로세스의 시스템 콜 추적
strace -p 1234
# 시스템 콜 통계
strace -c -p 1234
# 특정 시스템 콜만 추적
strace -e trace=open,read,write -p 1234
tcpdump: 네트워크 기반 CPU 부하 분석
# 특정 포트의 패킷 수 확인
tcpdump -i any port 80 -c 100
# DDoS 공격 탐지
netstat -an | grep :80 | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr
📊 CPU 성능 벤치마킹
stress: CPU 부하 테스트
# stress 설치
sudo yum install epel-release stress
sudo apt install stress
# CPU 4개 코어를 60초간 100% 사용
stress --cpu 4 --timeout 60s
# CPU와 메모리 동시 테스트
stress --cpu 2 --vm 2 --vm-bytes 1G --timeout 120s
sysbench: 종합 성능 테스트
# sysbench 설치
sudo yum install sysbench
sudo apt install sysbench
# CPU 성능 테스트
sysbench cpu --cpu-max-prime=20000 run
# 다중 스레드 CPU 테스트
sysbench cpu --cpu-max-prime=20000 --threads=4 run
⚠️ CPU 분석 시 주의사항
1. 측정이 시스템에 미치는 영향
모니터링 도구 자체도 CPU를 사용하므로:
- 적절한 샘플링 간격 설정
- 필요한 정보만 수집
- 백그라운드 실행 시 리소스 사용량 고려
2. 가상화 환경에서의 고려사항
# 가상화 환경에서 steal time 확인
top
# st(steal) 값이 높으면 호스트 서버 과부하 의심
# 컨테이너 환경에서 CPU 제한 확인
cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us
cat /sys/fs/cgroup/cpu/cpu.cfs_period_us
3. 멀티코어 시스템에서의 분석
# 코어별 사용률 확인
mpstat -P ALL 1 5
# NUMA 정보 확인
numactl --hardware
numastat
🔮 CPU 성능 최적화 고급 기법
1. 커널 매개변수 튜닝
# /etc/sysctl.conf 편집
sudo vim /etc/sysctl.conf
# CPU 스케줄링 관련 설정
kernel.sched_migration_cost_ns = 5000000
kernel.sched_autogroup_enabled = 0
# 적용
sudo sysctl -p
2. 프로세스 그룹 관리
# systemd를 이용한 리소스 제한
sudo systemctl edit my-service.service
# 다음 내용 추가:
[Service]
CPUQuota=50%
CPUWeight=100
3. 실시간 성능 조정
# 실시간 우선순위 확인
ps -eo pid,cls,rtprio,pri,ni,cmd | grep RT
# 실시간 프로세스 설정
chrt -f 50 ./critical_process
# IRQ 밸런싱 비활성화 (특정 상황에서)
sudo service irqbalance stop
🎯 마무리: 효과적인 CPU 분석 전략
리눅스에서 CPU 사용량 분석을 마스터하기 위한 핵심 포인트:
- 기본 도구 완전 숙달 → top, ps, sar, pidstat
- 실시간 + 히스토리 분석 → 현재 상황과 트렌드 모두 파악
- 계층적 접근 → 시스템 → 프로세스 → 스레드 순으로 분석
- 자동화된 모니터링 → 임계치 알림과 로그 수집 시스템 구축
- 지속적인 최적화 → 분석 결과 기반 튜닝과 검증
CPU 사용량 분석은 하루아침에 마스터할 수 있는 기술이 아닙니다. 다양한 상황에서 꾸준히 실습하고, 각 도구의 특성을 이해하며, 시스템의 동작 원리를 깊이 파악하는 것이 중요해요.
특히 문제 상황이 발생했을 때 당황하지 말고 체계적으로 접근하는 것이 핵심입니다. 전체적인 시스템 상태를 먼저 파악하고, 점차 세부적인 원인을 찾아나가는 습관을 기르시기 바랍니다.
💬 여러분의 CPU 분석 경험을 들려주세요! 어려웠던 성능 문제를 어떻게 해결하셨는지, 유용한 팁이 있다면 댓글로 공유해 주세요.
🔗 관련 글 더 보기: