본문 바로가기
서버 인프라 실무

시스템 모니터링 첫걸음: top/htop/journalctl/ss로 원인 추적(근거 있는 장애 대응 루틴)

by yamoojin83 2025. 10. 23.

시스템 모니터링 첫걸음: top/htop/journalctl/ss로 원인 추적(근거 있는 장애 대응 루틴)

장애가 나면 “느린 것 같아요”가 아니라 근거로 말해야 합니다. CPU·메모리·IO·네트워크·로그를 빠르게 스캔해 증상 → 원인 후보 → 확증 순서로 좁혀가는 루틴을 만들어 둡시다. Ubuntu 24.04 기준으로 top/htop/journalctl/ss 네 가지 도구만으로 대부분의 1차 진단을 끝내는 방법을 정리합니다.


1) 공통 원칙(응급 시 먼저 체크)

  • 증상 기록: 언제부터/어떤 요청에서 느린지(HTTP 코드·URL·사용자 수).
  • 시계 확인: chronyc tracking 오프셋이 큰지(로그 상관관계가 틀어지면 분석 불가).
  • 시스템 스냅샷: 아래 명령을 즉시 실행하여 캡처(근거 보존).
# 공통 스냅샷: 10초 간격 3회
date; uptime; who; free -m; df -h; vmstat 1 5; iostat -xz 1 5 2>/dev/null || true

2) top: “지금, 누가, 얼마나” 먹는가

top은 가볍고 빠릅니다. 상단 요약(로드·CPU·메모리)을 보고 하단 프로세스 표에서 가해자를 찾습니다.

top -H -o %CPU     # 스레드 단위(-H), CPU 내림차순
top -o %MEM        # 메모리 내림차순
  • load average가 코어 수보다 계속 높다면 과부하 가능성이 큼(대기 스레드가 많음).
  • %us가 높으면 순수 CPU 바운드, %sy↑는 시스템 콜/커널, %wa↑는 디스크 대기(IO wait) 의심.
  • 문제 프로세스의 PID를 잡고, 상세를 pslsof로 추가 조사.
# 문제 PID가 1234라면
ps -o pid,ppid,cmd,%cpu,%mem -p 1234
sudo lsof -p 1234 | head

3) htop: 직관형 대시보드(색상·트리·단축키)

htoptop보다 가독성이 좋고 프로세스 트리·검색·kill을 쉽게 지원합니다.

sudo apt install -y htop
htop
  • F5: 트리 보기(부모-자식 관계). 특정 자식 스파이크 파악에 유용.
  • F3: 검색, F6: 정렬 기준 변경, F9: 종료 신호 전송.
  • 상단의 CPU 막대가 한두 코어만 100%면 락 경합/싱글 스레드 병목 의심.

4) journalctl: 서비스 로그 타임라인으로 확증

증상과 프로세스를 봤다면 이제 원인을 확보해야 합니다. 시스템/서비스 로그를 시간순으로 좁혀봅니다.

# 부팅 이후 에러만
journalctl -p 3 -xb

# 특정 서비스(예: nginx)
journalctl -u nginx --since "30 min ago"

# 끊김 직전~이후 10분
journalctl --since "2025-10-15 13:00" --until "2025-10-15 13:10"
  • 동일 시각대에 에러/타임아웃/재시작 로그가 겹치는지 확인.
  • 커널 OOM 로그(Out of memory)가 보이면 메모리 부족 확정 → 문제 프로세스 메모리 사용·누수 조사.

5) ss: 포트·연결·대기열로 네트워크 병목 확인

ssnetstat의 현대적 대체입니다. 리스닝 포트, 대기열, ESTAB/WAIT, 송수신 버퍼를 점검합니다.

# 리스닝 소켓 목록
ss -lntup

# 특정 포트(예: 8080) 상태
ss -s; ss -ti '( sport = :8080 )'

# 클라이언트 IP 누적(상위 10)
ss -tn state established | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head
  • Send-Q/Recv-Q가 계속 쌓이면 애플리케이션/프록시의 처리 지연 또는 네트워크 혼잡.
  • ESTAB 폭증 시 커넥션 풀/스레드 풀 한계, TIME_WAIT 폭증 시 keep-alive/커넥션 전략 점검.

6) 원인 유형별 빠른 분기

6-1) CPU 바운드

  • 징후: top에서 %CPU↑, 특정 PID/스레드 고정 100%.
  • 조치: 스레드 풀 확장, 알고리즘/쿼리 개선, perf 또는 jcmd/jstack로 핫스팟 추적.

6-2) 메모리 부족/OOM

  • 징후: journalctl -k에 OOM 로그, free -m에서 캐시 외 여유 거의 없음.
  • 조치: 문제 프로세스 메모리 제한/튜닝, 누수 패턴 조사, 스왑 임시 확대, 트래픽 차단·스케일아웃.

6-3) IO wait/디스크 병목

  • 징후: top의 %wa↑, iostat -xz에서 %util 90%↑, await↑.
  • 조치: 로그/데이터 경로 분리, SSD/볼륨 스펙 업, 배치 작업 스케줄 조정, 캐시/버퍼링.

6-4) 네트워크 병목

  • 징후: ss Send-Q/Recv-Q↑, ESTAB 폭증, nginx 499/504 증가.
  • 조치: 프록시/백엔드 타임아웃 정합, 커넥션 풀/스레드 풀 조정, rate-limit·큐 도입, 상위 IP 차단.

7) 10분 진단 플레이북(복붙용)

  1. 시작 1분: date; uptime; top -H -o %CPU → 과부하/가해자 파악.
  2. 로그 3분: journalctl -p 3 -xb, journalctl -u <서비스> --since "15 min ago".
  3. 네트워크 2분: ss -lntup, ss -s, ss -tn state established | awk ....
  4. IO 2분: iostat -xz 1 5 / vmstat 1 5.
  5. 스냅샷 보존 2분: 위 결과를 파일로 저장해 공유(script 명령 사용).
# 세션 기록(증거 보존)
script -q /tmp/incident.$(date +%F_%T).log
# ...여기서 진단 명령 실행...
exit

8) “느려요”를 수치로 바꾸는 미니 지표

  • CPU: load average vs 코어 수, 병목 PID의 %CPU.
  • 메모리: free -m·swap, OOM 여부.
  • 디스크: iostat -xz%util, await (ms).
  • 네트워크: ss -s 연결 수, Send-Q/Recv-Q.
  • 서비스: 에러율(5xx), p95 지연(로그/리버스 프록시 메트릭).

9) 예방 세팅(상시 운영)

  • 로그 영구화: /var/log/journal 생성 → 재부팅 후에도 로그 유지.
  • 리소스 알람: node_exporter + Prometheus + Grafana(로드/메모리/디스크/네트워크 대시보드).
  • 프로세스 제한: systemd CPUQuota/MemoryMax로 폭주 방지.
# /etc/systemd/system/myapp.service (발췌)
[Service]
CPUQuota=150%
MemoryMax=1G
Restart=on-failure

10) FAQ

Q1. top과 htop, 무엇을 기본으로?
A. 서버 접속이 느릴 때는 top이 더 가볍습니다. 여유가 있으면 htop으로 트리/검색/kill을 활용하세요.

Q2. ss에서 Send-Q가 계속 쌓일 때?
A. 앱/프록시가 응답을 빨리 내지 못하거나 커넥션 대상이 느린 것입니다. 타임아웃, 워커/스레드/큐, DB/외부 API 지연을 함께 보세요.


11) 최종 체크리스트

  • CPU/메모리/IO/네트워크를 각각 한 줄 명령으로 스냅샷.
  • top/htop에서 가해자 PID → ps/lsof로 확증.
  • journalctl로 같은 시간대 에러/재시작/OOM 확인.
  • ss로 포트·대기열·연결 폭증 탐지.
  • 증거(log 파일) 저장 및 공유로 재현 없는 해결 가속.

이 네 가지 도구만 익숙해져도 “느린 것 같음”을 수치와 원인으로 바꿀 수 있습니다. 다음 글에서는 백업 자동화와 스케줄링을 위한 rsync/cron 실전 운영 패턴을 다룹니다.