리눅스 서버 CPU 점유율 갑자기 오를 때 원인 프로세스 찾는 명령어와 재부팅 없는 해결법
- 공유 링크 만들기
- X
- 이메일
- 기타 앱
리눅스 서버 CPU 점유율 갑자기 오를 때 원인 프로세스 찾는 명령어와 재부팅 없는 해결법
리눅스 서버를 운영하다 보면 누구나 한 번쯤 등골이 서늘해지는 경험을 하게 됩니다. 잘 돌아가던 서비스가 갑자기 느려지거나, 모니터링 알람이 빗발치며 CPU 사용률이 90% 이상을 치솟는 상황은 시스템 엔지니어와 백엔드 개발자 모두에게 악몽과도 같습니다. 특히 클라우드 환경에서 오토스케일링이 제대로 설정되어 있지 않거나, 단일 인스턴스로 운영되는 레거시 서버라면 문제는 더욱 심각해집니다.
단순히 서버를 재부팅하는 것은 임시방편일 뿐, 근본적인 원인을 해결해주지 못합니다. 재부팅 후 잠시 괜찮아졌다가 다시 CPU 점유율이 오르는 현상이 반복되면 결국 서비스 신뢰도는 바닥으로 떨어지게 됩니다. 따라서 우리는 정확한 명령어를 통해 어떤 프로세스가 리소스를 잡아먹고 있는지, 그것이 애플리케이션의 로직 문제인지, I/O 병목인지, 아니면 시스템 커널의 문제인지를 명확하게 파악해야 합니다.
이 글에서는 리눅스 서버 CPU 점유율이 갑자기 오를 때 원인 프로세스를 찾는 핵심 명령어와 분석 방법, 그리고 상황별 대처 가이드를 아주 상세하게 다루어 보겠습니다. 실무에서 바로 적용할 수 있도록 구체적인 옵션과 해석 방법을 포함하여, 초보자부터 숙련된 엔지니어까지 모두에게 도움이 되는 정보를 제공합니다.
1. 실시간 모니터링의 기본: top과 htop 완벽 분석
CPU 스파이크가 발생했을 때 가장 먼저 실행해야 하는 명령어는 단연코 top입니다. 하지만 많은 분들이 top 명령어를 실행한 후 단순히 상단에 떠 있는 프로세스 이름만 확인하고 넘어가는 경우가 많습니다. top 명령어는 우리가 생각하는 것보다 훨씬 더 방대한 정보를 실시간으로 제공하며, 이를 제대로 해석할 줄 알아야 정확한 진단이 가능합니다.
top 명령어의 핵심 지표 해석하기
터미널에 top을 입력하면 가장 윗줄에 Load Average라는 항목이 보입니다. 이는 1분, 5분, 15분 동안의 평균 시스템 부하를 나타냅니다. 단순히 숫자가 높다고 해서 무조건 나쁜 것은 아닙니다. 현재 서버의 CPU 코어 개수와 비교해야 합니다. 예를 들어, 4코어 서버에서 Load Average가 4.0이라면 CPU가 100% 효율로 꽉 차서 일하고 있다는 뜻이지만, 10.0을 넘어간다면 처리되지 못하고 대기 중인 프로세스가 많다는 뜻으로 심각한 병목 현상을 의미합니다.
또한 %CPU(us, sy, ni, id, wa, hi, si, st) 라인을 주의 깊게 봐야 합니다. 여기서 'us'는 사용자 레벨(애플리케이션)의 사용률이고, 'sy'는 커널(시스템) 레벨의 사용률입니다. 만약 'us'가 높다면 자바 애플리케이션이나 파이썬 스크립트 등 특정 프로그램이 CPU를 많이 쓰는 것이므로 코드를 최적화해야 합니다. 반면 'sy'가 높다면 너무 많은 시스템 콜이 발생하거나 드라이버 호환성 문제일 수 있습니다. 특히 'wa' (I/O Wait) 수치가 높다면 이는 CPU 문제가 아니라 디스크 입출력이 느려서 CPU가 놀고 있는 상황이므로 디스크 성능을 점검해야 합니다.
top 실행 상태에서 'P' 키(대문자)를 누르면 CPU 사용률 순으로 정렬되고, 'M' 키를 누르면 메모리 사용률 순으로 정렬됩니다. 숫자 '1'을 누르면 멀티코어 CPU의 각 코어별 사용량을 개별적으로 확인할 수 있습니다. 특정 코어만 100%를 치고 있다면 단일 스레드로 동작하는 프로세스가 병목을 일으키고 있을 확률이 매우 높습니다.
시각적 분석의 강자, htop 활용법
top 명령어가 텍스트 기반이라 가독성이 떨어진다면, htop을 설치하여 사용하는 것을 강력히 추천합니다. htop은 컬러풀한 인터페이스와 함께 마우스 조작을 지원하며, 프로세스 트리를 직관적으로 보여줍니다. 기본 리눅스 패키지에 포함되지 않은 경우가 많으므로 별도 설치가 필요할 수 있습니다.
htop의 가장 큰 장점은 F5 키를 눌러 트리 뷰(Tree View) 모드로 전환할 수 있다는 점입니다. 이를 통해 부모 프로세스와 자식 프로세스의 관계를 한눈에 파악할 수 있습니다. 예를 들어, 아파치나 Nginx 웹 서버, 혹은 PHP-FPM과 같은 프로세스들은 부모 프로세스 아래에 수많은 자식 프로세스를 생성합니다. CPU 점유율이 높은 프로세스가 어떤 부모에서 파생되었는지 알면 문제의 범위를 좁히기가 훨씬 수월해집니다.
또한 htop에서는 프로세스를 선택하고 F9 키를 눌러 즉시 종료(Kill) 신호를 보낼 수 있습니다. 긴급한 장애 상황에서 PID를 외워서 kill 명령어를 치는 번거로움을 줄여주어 운영자의 대응 속도를 높여줍니다. 다만, 무분별한 프로세스 강제 종료는 데이터 손실을 유발할 수 있으므로 신중해야 합니다.
💡 전문가 팁: top 명령어 실행 중 화면이 너무 빨리 갱신되어 프로세스 ID를 확인하기 어렵다면, 'd' 키를 누르고 갱신 주기(Delay)를 3초나 5초 정도로 늘려보세요. 훨씬 여유롭게 분석할 수 있습니다.
2. 정밀 분석을 위한 ps 명령어와 정렬 옵션
실시간 모니터링 도구인 top은 계속 변하는 값 때문에 특정 순간의 상태를 기록하거나 스크립트로 자동화하기 어렵습니다. 이때 필요한 것이 바로 ps 명령어입니다. ps 명령어는 현재 실행 중인 프로세스의 스냅샷을 출력해주므로, 로그 파일로 저장하여 나중에 분석하거나 특정 조건에 맞는 프로세스만 골라낼 때 유용합니다.
CPU 사용률 기준으로 프로세스 나열하기
가장 기본적인 ps -ef 명령어는 너무 많은 정보를 무작위로 보여주기 때문에 분석에 적합하지 않습니다. 우리가 원하는 것은 'CPU를 많이 쓰는 순서대로' 보는 것입니다. 이를 위해 ps 명령어에 사용자 정의 포맷 옵션(-eo)과 정렬 옵션(--sort)을 조합해야 합니다.
- ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%cpu | head -n 10
- 이 명령어 조합은 PID, 부모 PID, 명령어, 메모리 사용률, CPU 사용률을 출력하되, CPU 사용률이 높은 순서대로 내림차순 정렬하여 상위 10개만 보여줍니다.
- 서버가 느려졌을 때 이 명령어를 실행하여 결과를 파일로 리다이렉션 해두면, 나중에 어떤 프로세스가 범인이었는지 확실한 증거를 남길 수 있습니다.
이 명령어는 특히 젠킨스(Jenkins)와 같은 CI/CD 도구에서 빌드 작업이 과도하게 CPU를 점유할 때나, 데이터 분석 스크립트가 무한 루프에 빠졌을 때 유용하게 사용됩니다. 단순히 프로세스 이름만 나오는 것이 아니라 실행 시 부여된 옵션까지 cmd 항목에서 확인할 수 있어 구체적으로 어떤 작업이 돌고 있는지 파악이 가능합니다.
특정 사용자의 프로세스만 추적하기
여러 개발자가 공유하는 개발 서버나, 다양한 서비스 계정이 존재하는 운영 서버에서는 특정 사용자(User)가 실행한 프로세스가 문제를 일으키는 경우가 많습니다. 예를 들어 'tomcat' 계정이나 'mysql' 계정으로 실행된 프로세스만 집중적으로 보고 싶을 때가 있습니다.
이때는 ps -u [사용자명] 옵션을 사용하면 됩니다. 예를 들어 ps -u tomcat -o pid,%cpu,cmd --sort=-%cpu 명령을 내리면 tomcat 사용자가 실행한 프로세스들 중에서 CPU 사용률이 높은 순서대로 정렬해 줍니다. 이는 멀티 테넌트 환경이나 공유 호스팅 환경에서 리소스를 과점하고 있는 '노이즈 네이버(Noisy Neighbor)'를 찾아내는 데 매우 효과적입니다.
또한, 좀비 프로세스를 찾는 데에도 ps 명령어가 활용됩니다. 프로세스 상태 코드(STAT)가 'Z'로 표시되는 좀비 프로세스는 시스템 리소스를 크게 점유하지는 않지만, 프로세스 테이블을 차지하여 새로운 프로세스 생성을 방해할 수 있습니다. ps aux | grep 'Z' 명령어로 좀비 프로세스를 찾아내고, 그 부모 프로세스를 찾아 적절히 조치하는 것이 시스템 안정성을 위해 필요합니다.
3. 심층 분석: pidstat과 멀티 스레드 추적
top과 ps가 숲을 보는 도구라면, pidstat과 스레드 분석 명령어는 나무 하나하나, 나아가 나뭇잎을 살펴보는 현미경과 같습니다. 특히 최신 애플리케이션들은 대부분 멀티 스레드 기반으로 동작하기 때문에, 프로세스 하나만 봐서는 정확한 병목 지점을 찾기 어렵습니다. 자바(Java) 기반의 스프링 부트 애플리케이션이나 파이썬의 멀티 스레딩 모듈을 사용하는 경우라면 이 단계가 필수적입니다.
pidstat으로 사용자/시스템 모드 구분하기
sysstat 패키지에 포함된 pidstat 명령어는 특정 프로세스의 CPU 사용량을 주기적으로 관찰할 때 매우 강력합니다. pidstat 1 명령을 입력하면 1초마다 활성화된 프로세스들의 CPU 통계를 출력해 줍니다. 여기서 주목할 점은 %usr(사용자)와 %system(시스템) 사용량을 분리해서 보여준다는 점입니다.
만약 특정 데이터베이스 프로세스가 %system 수치가 비정상적으로 높다면, 이는 쿼리 처리가 아니라 파일 시스템 접근이나 네트워크 소켓 처리 과정에서 커널 레벨의 부하가 걸리고 있다는 뜻입니다. 반면 %usr가 높다면 복잡한 연산이나 정규표현식 처리 등 순수 애플리케이션 로직이 원인입니다. 이 구분은 튜닝의 방향을 결정하는 데 결정적인 역할을 합니다.
자바 애플리케이션의 특정 스레드 찾기 (top -H)
자바 애플리케이션이 CPU를 100% 사용하고 있다고 가정해 봅시다. PID가 1234라고 할 때, 단순히 "자바가 문제네"라고 결론 내리는 것은 아무런 도움이 되지 않습니다. 자바 내부의 GC(Garbage Collection) 스레드가 문제인지, 특정 API를 처리하는 워커 스레드가 무한 루프에 빠진 것인지 알아야 합니다.
이때 사용하는 명령어가 top -H -p [PID]입니다. -H 옵션은 프로세스 내의 스레드(Thread)를 개별적으로 보여주는 옵션입니다. 이 명령어를 실행하면 해당 자바 프로세스 내부의 수십, 수백 개의 스레드가 나열되고, 그중 실제로 CPU를 소모하고 있는 특정 스레드 ID(TID)를 찾을 수 있습니다.
여기서 찾은 TID를 16진수로 변환한 뒤, 자바의 스레드 덤프(jstack) 결과와 매칭하면 정확히 소스 코드의 몇 번째 줄에서 CPU를 점유하고 있는지 핀포인트로 찾아낼 수 있습니다. 이는 개발자가 코드를 수정하여 성능 문제를 해결하는 데 가장 직접적인 단서를 제공합니다.
⚠️ 주의사항: pidstat 명령어가 없다면yum install sysstat또는apt-get install sysstat명령어로 패키지를 먼저 설치해야 합니다. 실무 서버에는 기본적으로 설치해두는 것이 좋습니다.
🔎 관련 상품 추천
아래 링크를 통해 구매 시 운영자에게 일정 수수료가 발생할 수 있습니다.
리눅스 서버 CPU 점유율 갑자기 오를 때 원인 프로세스 찾는 명령어
'리눅스 서버 CPU 점유율 갑자기 오를 때 원인 프로세스 찾는 명령어' 관련 상품을 쿠팡에서 확인해 보세요.
상품 보러가기 →
아래 링크를 통해 구매 시 운영자에게 일정 수수료가 발생할 수 있습니다.
'리눅스 서버 CPU 점유율 갑자기 오를 때 원인 프로세스 찾는 명령어' 관련 상품을 쿠팡에서 확인해 보세요.
상품 보러가기 →- 공유 링크 만들기
- X
- 이메일
- 기타 앱
댓글
댓글 쓰기