서버 CPU 사용률이 높다는 것은 단순히 “바쁘다”는 의미가 아니다.
정상 트래픽인지, 비정상 반복 연산인지, 특정 프로세스 폭주인지 구분해야 한다.
무작정 서버 스펙을 올리는 것은 해결이 아니다.
CPU가 왜 올라갔는지 원인을 찾는 것이 우선이다.
1. 1차 확인 — 어떤 프로세스가 CPU를 사용하는가
가장 먼저 할 일은 CPU를 점유하는 프로세스를 확인하는 것이다.
전체 사용률보다 “누가 사용 중인가”가 중요하다.
top
%CPU 항목을 기준으로 상위 프로세스를 확인한다.
nginx, php-fpm, mysql, node 등 어떤 계층에서 부하가 발생하는지 먼저 구분한다.
좀 더 상세히 보고 싶다면 다음 명령어를 사용한다.
htop
ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%cpu | head
2. 사용자 영역인지 시스템 영역인지 구분
CPU 사용률은 user, system, idle, iowait 등으로 나뉜다.
iowait이 높다면 디스크 병목일 가능성이 있다.
top
# 또는
vmstat 1
us(user)가 높으면 애플리케이션 로직 과부하일 가능성이 크다.
wa(iowait)가 높다면 디스크 I/O가 병목일 수 있다.
3. 웹 애플리케이션 레벨 점검
PHP, Node 등 애플리케이션이 CPU를 점유하고 있다면
특정 요청이 과도한 연산을 수행하는지 확인해야 한다.
- 무한 루프 존재 여부
- 대량 데이터 반복 처리
- N+1 쿼리 문제
- 대용량 파일 처리
특정 API 호출 시 CPU가 급증한다면 해당 엔드포인트를 중심으로 분석한다.
로그와 함께 요청 패턴을 확인한다.
tail -f /var/log/nginx/access.log
동일 IP에서 반복 요청이 있다면 트래픽 공격 가능성도 고려해야 한다.
4. DB 레벨 점검
MySQL 프로세스가 CPU를 점유하고 있다면 슬로우 쿼리를 의심한다.
인덱스를 타지 않는 풀스캔 쿼리가 반복 실행되면 CPU가 급격히 상승한다.
SHOW PROCESSLIST;
동일 쿼리가 반복 실행되는지 확인한다.
EXPLAIN으로 실행계획을 점검한다.
EXPLAIN SELECT ...
type이 ALL이면 풀테이블 스캔이다.
이 경우 인덱스 설계가 필요하다.
5. 트래픽 증가인지 구조 문제인지 구분
CloudWatch나 모니터링 도구에서 트래픽 그래프와 CPU 그래프를 함께 본다.
트래픽과 함께 상승하면 정상 부하일 가능성이 있다.
트래픽 변화 없이 CPU만 상승하면 코드 또는 쿼리 구조 문제일 가능성이 크다.
6. 자주 발생하는 원인
- 인덱스 미설계로 인한 풀스캔
- N+1 쿼리 문제
- 무한 루프 또는 재귀 폭주
- 로그 폭증
- 크롤링/봇 트래픽
원인을 찾지 않고 재시작만 반복하면 장애는 반복된다.
재시작은 임시 조치일 뿐이다.
7. 대응 전략
- 슬로우 쿼리 로그 활성화
- 캐시 도입 (Redis 등)
- API 요청 제한(Rate Limit)
- Auto Scaling 구성
- 코드 리팩토링
튜닝과 확장은 순서가 있다.
먼저 구조를 개선하고, 이후에도 부족하면 스케일을 확장한다.
한 줄 요약
CPU 상승 시 상위 프로세스 확인 → user/iowait 구분 → 애플리케이션·DB 분석 → 트래픽 패턴 비교 → 구조 개선 후 확장 순서로 접근하면 근본 원인을 찾을 수 있다.
댓글 0