【Ubuntu】CPU100%の調べ方:top/ps/load average で原因プロセスを特定する(再発防止まで)

CPU高負荷トラブルシューティング - top/ps

この記事で解決できること

  • CPUが100%近く張り付いたときに、原因プロセスを最短で特定できます
  • 「CPUが原因」なのか、「I/O待ち」や「スワップ地獄」なのかを切り分けできます
  • 一時復旧(再起動)だけで終わらせず、次に繋がる証拠(ログ・値)を残せます

結論(最短ルート)

CPUが高いときは、次の順で見れば迷いません。

  1. まず全体状況uptime(load average)
  2. topで犯人を見るtop(CPU順、%us/%sy/%wa も見る)
  3. psで上位を確定ps aux --sort=-%cpu | head
  4. サービスならログへsystemctl status / journalctl -u
  5. CPUに見えて実は…を除外:I/O待ち(wa)/メモリ不足(swap)

目次

  1. 「CPU100%」は2種類ある
  2. uptime で load average を見る
  3. top で「犯人」と「CPU内訳」を見る
  4. ps でCPU上位を確定する
  5. サービスなら systemctl / journalctl
  6. 「CPUに見えて実は…」を潰す
  7. よくある原因パターン
  8. やってはいけないこと

前提(対象環境)

  • OS:Ubuntu
  • 対象:サーバ触り始めた新人
  • sudo 可能
  • 目的:切り分け → 原因特定 → 再発防止の入口

1. 「CPU100%」は2種類ある(ここが盲点)

CPUが高いとき、原因はだいたい次のどちらかです。

タイプA:本当にCPU計算が重い

  • 計算/ループ/暗号化/変換/集計
  • topで特定プロセスがCPUを食っている
  • %us(ユーザーCPU)が高いことが多い

タイプB:CPUが高いように見えるが、実はI/O待ち・メモリ不足

  • ディスクが遅い(ログ肥大、DB、EBS劣化、I/O上限)
  • Swapが増えて激重(メモリ不足)
  • %wa(I/O wait)が高いことが多い

"CPU100%だからCPUを増やす" は早計です。まず %wa と swap を見て「本当にCPUか?」を確定します。

2. まず uptime で load average を見る(全体の圧を知る)

$ uptime

出力例:

 14:05:12 up 10 days,  3:20,  2 users,  load average: 3.52, 3.10, 2.90

load average とは(新人向けに最小限):

  • CPUコア数が4なら、loadが 4前後 で "混んでる"
  • loadが 10 とかなら、かなり詰まってる

ただし load はCPUだけでなくI/O待ちも含むので、次の top で中身を見る必要があります。

3. top で「犯人」と「CPU内訳」を見る

$ top

3-1. top の操作(必須)

  • P:CPU順に並べ替え
  • M:メモリ順(メモリ不足が疑わしいとき)
  • 1:CPUコアごとの表示(マルチコアで偏りを見る)
  • q:終了

3-2. CPU内訳(%us / %sy / %wa)を読む

topの上部に出ます。

  • %us:アプリが計算してCPUを使っている
  • %sy:カーネル/システム処理が多い(ネットワーク/ディスク/割り込みなど)
  • %wa:I/O待ち(ディスクが遅い・詰まってる)

判断の例:

  • %us が高い → アプリ処理が重い(タイプA)
  • %wa が高い → I/Oが詰まってる(タイプB)
  • %sy が高い → システム側の処理が多い

4. ps でCPU上位を確定する(証拠を残す)

topは一瞬の状態ですが、psで一覧を残せます。

$ ps aux --sort=-%cpu | head -n 20

特に見るべき列:

  • COMMAND:何がCPUを食っているか
  • %CPU:どれが突出しているか

もし同じ種類が大量なら(ワーカー増殖)、上限設定が無い/負荷が高すぎる方向に寄ります。

5. プロセスがサービスなら systemctl / journalctl

プロセスが nginx や apache2 ではなく、アプリ(php-fpm、node、gunicorn等)なら、ログに原因が出ていることが多いです。

5-1. サービス状態

$ sudo systemctl status nginx
$ sudo systemctl status apache2
$ sudo systemctl status php8.1-fpm

5-2. ログ(直近200行)

$ sudo journalctl -u nginx -n 200
$ sudo journalctl -u php8.1-fpm -n 200

CPUが高いときは、同時に「大量リクエスト」「エラー連発」「再起動ループ」が起きがちです。まずはログで "何が連発しているか" を見ます。

6. 「CPUに見えて実は…」を潰す(重要)

ここを飛ばすと、対策を間違えます。

6-1. メモリ不足(Swap)の有無を確認

$ free -h

Swapが増えている/availableが小さい場合、CPU問題に見えても根がメモリの可能性があります。

6-2. I/O待ち(%wa)が高いなら、ディスクI/Oを疑う

  • ログ肥大
  • DB
  • Dockerのレイヤ増殖
  • ストレージ性能不足
$ iostat -x 1 5

I/O待ちが原因なら、CPUを増やしても改善しないことが多いです。

7. よくある原因パターン(現場で多い順)

パターン1:無限ループ/バグ/暴走

  • 1プロセスがずっとCPUを占有(%us高)
  • 対処:ログ・直前のデプロイ・最近の変更点を確認

パターン2:ボット/スキャン/アクセス集中

  • nginx/apacheのaccessが爆増
  • 対処:Webログを見る、レート制限/WAF/キャッシュ検討

パターン3:ワーカー過多(php-fpm等)

  • 子プロセスが増え続けてCPUもメモリも食う
  • 対処:ワーカー数の上限設定(MaxChildrenなど)

パターン4:I/Oが遅くて詰まり、結果CPUが高く見える

  • %waが高い
  • 対処:ディスクI/O調査

8. やってはいけないこと

やってはいけない1:証拠を取らずに再起動

最低限、これを残してから判断してください。

  • uptime
  • free -h
  • ps aux --sort=-%cpu | head
  • top(可能なら画面キャプチャ)

やってはいけない2:%waを見ずにCPU増強

I/O待ちならCPU増強は無駄打ちになりがちです(機会損失)。

やってはいけない3:ワーカー上限なしを放置

アクセスが増えた瞬間に壊れます。上限を設けるのが先です。

コピペ用:CPU高負荷 調査テンプレ

# 1) 全体
uptime

# 2) メモリも同時に(CPUに見えて実は…を潰す)
free -h

# 3) CPU上位(証拠)
ps aux --sort=-%cpu | head -n 20

# 4) topで内訳(%us/%sy/%wa)と犯人確認
top

# 5) サービスならログ
sudo systemctl status <service>
sudo journalctl -u <service> -n 200

まとめ

  • CPU高負荷は「本当にCPU」か「I/O待ち/メモリ不足」をまず分ける
  • uptime → top → ps → journalctl の順が最短
  • 再起動は最後。証拠を残してから判断する

検証環境

本記事のコマンドは Ubuntu 24.04 LTS / bash 5.2 で動作確認済みです。

次に読む