Closed7

サーバーが重い...ときに確認すること

mom0tomomom0tomo

ロードアベレージを確認する

$ uptime
11:03  up 6 days, 19:17, 7 users, load averages: 4.88 6.90 7.32
mom0tomomom0tomo

ロードアベレージが低い場合

ネットワークの問題の可能性がある。
TCPコネクションが異常に大量に張られていないか確認する。(TCPコネクション数の上限に張り付いている可能性がある)

$ netstat -an | wc -l
414

# 使っているポートを待機中のものも含めてすべて表示する「-a」
# 名前解決をせずに数字で表示する「-n」
mom0tomomom0tomo

ロードアベレージが高い場合

CPU利用率を確認する

CPU使用率がほぼ100%になっていたらCPUがボトルネックになっている。

$ top -c
top - 11:10:14 up 1058 days, 15:03,  1 user,  load average: 0.06, 0.04, 0.05
Tasks: 157 total,   1 running, 156 sleeping,   0 stopped,   0 zombie
%Cpu(s):  2.9 us,  5.7 sy,  0.0 ni, 91.4 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
...

id=アイドル状態なので、100-id(=ここでは8.6)がCPU使用率になる。

top -cもしくはpsコマンドでどのプロセスが原因になっているかを調査する。

$ ps auxf
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root     25805  0.0  0.1  64264  4072 ?        Ss    2015   0:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
nginx    25806  2.6  0.7  70196 15224 ?        S     2015 2691:21  \_ nginx: worker process
nginx    25807  2.7  0.8  71700 16416 ?        S     2015 2725:39  \_ nginx: worker process
...
# メモリ利用率でソートしてみることもある

$ ps auxf --sort -%mem

DBサーバーの場合はSHOW processlist;で長時間実行したままのクエリがないか(=クエリが刺さっている)確認する。

mysql> SHOW processlist;
| 198276 | xx | 10.xx.xx.xx:36336 | test_db | Query   | 517824 | statistics | SELECT DISTINCT `xxx`.* FROM `xxx` INNER JOIN `users` ON `users`.`id` =..|
mom0tomomom0tomo

スワップが発生していないか確認する

freeコマンドでSwapのusedを確認する。

$ free -h
              total        used        free      shared  buff/cache   available
Mem:           3.7G        1.1G        747M        366M        1.8G        1.8G
Swap:          1.0G         74M        949M

スワップが発生するのはメモリが不足したということなので、psコマンドで特定のプロセスがメモリを大量消費していないか確認する。

mom0tomomom0tomo

ディスクI/Oを確認する

直近リリースしたプログラムが激しいI/Oを行っていないか開発者に確認する。
(よくあるのはDBサーバーで、一括取得のSELECT(READ)とか、それをCSVに書き込む(WRITE)とか。全件検索&ダンプ出力でメモリにも乗らない処理をバッチで行なっていたり)

必要に応じて処理の分割やキャッシュサーバの導入、メモリ増設を検討する。

mom0tomomom0tomo

最終手段のstrace

# 怪しいプロセスをstraceしてみる
$ sudo strace -p {なんか怪しいプロセスのプロセス番号}
# I/Oのプロセスのどこで詰まっているのか当たりがつけられる
Process 10471 attached - interrupt to quit
read(58,  <unfinished ...>
Process 10471 detached

# lsofでプロセスIDを指定して見る
$ lsof -i -a -p {なんか怪しいプロセスのプロセス番号}

# 直接プロセス見てもいい
# sudo readlink /proc/{なんか怪しいプロセスのプロセス番号}/fd/ファイルディスクリプタ番号
$ sudo readlink /proc/10471/fd/58
socket:[1148032788]

# netstat からソケット番号でgrepして接続先を発見する
$ netstat -ane | grep 1148032788
tcp        0      0 10.0.0.10:44566            10.0.0.11:3306           ESTABLISHED 48         1148032788

参考

このスクラップは2022/11/28にクローズされました