カーネルパニック
サーバの監視アラートが発報されサーバが落ちていることが発覚し調査した。SSHでの接続は不可能だったので、さくらVPSのコントロールパネルから状態を確認。画面には「kernel panic」の文字。操作できなかったのでコンパネ上から再起動しサーバは復帰した。
原因究明
messagesログを確認すると「httpd invoked oom-killer: ~」というログを発見。どうやらメモリが枯渇しサーバが落ちた模様。以下が障害の流れ。
メモリ枯渇→oom-killer→カーネルパニック
oom-killerとは
物理メモリ、スワップメモリが枯渇したとき、システム全体に最も影響の与えてるプロセス(メモリを一番使っている)を選択しkillするプログラムのこと。init プロセスやカーネルスレッドなどは OOM Killer 発動対象外。
スワップメモリ追加
メモリは物理が4G、スワップが2G。スワップメモリがかなり少なかったので応急処置としてスワップメモリを6Gに増やした。
# dd if=/dev/zero of=作成ファイル bs=ブロックサイズ count=ブロック数 dd if=/dev/zero of=/var/swpfile4G bs=1M count=4096
ddコマンドで4Gの空ファイルを作成する。
mkswap /var/swpfile4G
mkswapでフォーマットしスワップとして使用できるようにする。
chmod 600 /var/swpfile4G
このままでは権限のエラーがでるのでパーミッション変更。
swapon /var/swpfile4G
スワップ領域を割り当てる
free
freeコマンドで確認。
vi /etc/fstab #最終行に以下を追加 /var/swpfile4G swap swap defaults 0 0
OS再起動時に追加したSwap領域がマウントするようにfstabファイルを編集。
プロセスチェック
以下のコマンドを利用してメモリを使っているプロセスを割り出した。調査すると落ちたサーバがWEBサーバとして利用していることもあり「httpd」が一番怪しかった。Apacheの設定を確認すると「MaxClients」の値が256あり、1プロセス当たりのメモリ使用量が50Mの場合、12Gのメモリを使用することになり完全に枯渇することがわかった。
#ランキング ps -eo comm,rss | sort -rn -k 2 | head -n 50 #指定プロセスの物理メモリ(RSS)合計 ps -eo rss,comm | awk 'BEGIN {SUM=0} {if ($2 == "[プロセス名]"){ SUM+=$1 }} END {printf("%dMB\n", SUM/1024)}' #指定プロセス数 ps -eo rss,comm | awk 'BEGIN {COUNT=0} {if ($2 == "[プロセス名]"){ COUNT+=1 }} END {print COUNT}' #指定プロセスの物理メモリ(RSS)平均 ps -eo rss,comm | awk 'BEGIN {SUM=0;COUNT=0} {if ($2 == "[プロセス名]d"){ SUM+=$1;COUNT+=1 }} END {printf("%dKB\n", SUM/COUNT)}' #指定プロセスの物理メモリ(RSS)最大 ps -eo rss,comm | awk 'BEGIN {MAX=0} {if ($2 == "[プロセス名]"){ if (MAX < $1) { MAX=$1 }}} END {print MAX}' #指定プロセスのCPU使用率 ps -eo %cpu,comm | awk 'BEGIN {SUM=0} {if ($2 == "[プロセス名]"){ SUM+=$1 }} END {print SUM}'
ちなみに主要プロセスのメモリ使用量は以下になった。
Postfixメモリ使用量:約33MB
PHPメモリ使用量 :0MB
MySQLメモリ使用量 :75.51 MB
httpdメモリ使用量 :443.44 MB
clamメモリ使用量 :806.4 MB
clamがメモリの使用量が大きかったので一旦停止した。
Apacheのチューニング
プロセスチェックの結果からApacheの設定に問題があることがわかりチューニングした。
以下チューニングに関係するディレクティブ。
・StartServers
Apache起動時の子プロセス数
・MinSpareServers
待機時の最小子プロセス数
・StartServers
Apache起動時の子プロセス数
・MinSpareServers
待機時の最小子プロセス数
・MaxSpareServers
待機時の最大子プロセス数
・ServerLimit
設定可能なサーバプロセス数の上限
・MaxClients
最大の小プロセス数
・MaxRequestsPerChild
1子プロセスが処理するリクエスト数(上限を超えると新しいプロセスに入れ替わる)
実際設定したのは以下の設定。
サーバが落ちた時の設定内容(デフォルト値) <IfModule prefork.c> StartServers 8 MinSpareServers 5 MaxSpareServers 20 ServerLimit 256 MaxClients 256 MaxRequestsPerChild 4000 </IfModule>
↓
<IfModule prefork.c> StartServers 25 MinSpareServers 25 MaxSpareServers 40 ServerLimit 105 MaxClients 100 MaxRequestsPerChild 1000 MaxMemFree 2048 </IfModule>
「MaxSpareServers」はメモリが枯渇しないように設定。「MaxClients」は始め50ぐらいに設定していたが、すぐに上限に到達したので(apacheのエラーログでわかる)調整し100ぐらいに落ち着いた。
Zabbixでプロセスの監視
Zabbixでプロセスの監視をすることにした。今後これらの値を参考にさらなるチューニングなどに生かしていく。
テンプレートを作成しアイテムを追加する。
以下プロセスのメモリ容量を監視。
・postfixメモリ使用量
・phpメモリ使用量
・mysqldメモリ使用量
・httpdメモリ使用量
・clamメモリ使用量
あとはapacheのプロセス数、1プロセス当たりの平均メモリ使用量を監視。
プロセス名メモリ使用量
アイテム追加
名前:プロセス名メモリ使用量 タイプ:エージェント キー:proc.mem[プロセス名,,sum,,rss] データ型:数値(整数) データ形式:10進数 単位:B
プロセス名はpostfix、php、mysqld、httpd、clamを入れる。
httpdの1プロセス当たりの平均メモリ使用量
アイテム追加
名前:httpdメモリ使用量平均 タイプ:エージェント キー:proc.mem[httpd,,avg,,rss] データ型:数値(整数) データ形式:10進数 単位:B
httpdプロセス数
アイテム追加
名前:httpdプロセス数 タイプ:エージェント キー:proc.num[httpd,,,] データ型:数値(整数) データ形式:10進数
Zabbixでログ監視
ログを監視し問題のあるものはアラートを飛ばす設定にした。
テンプレートを作成しアイテム追加、トリガーを追加する。
messages監視
以下の設定でmessagesログを監視し「oom-killer」が出たらアラートを飛ばすようにする。
アイテム追加
名前:messagesログ監視 タイプ:アクティブ キー:log[/var/log/messages,,,,,] データ型:ログ
トリガー
名前:OOM killer が発動されました。 条件式: {Template linux logs:log[/var/log/messages,,,,,].regexp(oom-killer)}=1 and {Template linux logs:log[/var/log/messages,,,,,].nodata(10m)}=0
apacheのエラーログ
以下の設定でapacheのエラーログを監視し「MaxClients」が出たらアラートを飛ばすようにする。
このアラートは、apacheのプロセス数が「MaxClients」の値に到達したことを意味し再チューニングの参考にできる。
・アイテム
名前:apache error_log タイプ:アクティブ キー:log[/var/log/httpd/error_log,,,,,] データ型:ログ
トリガー
名前:apacheのプロセスが上限に達しました。 条件式: {Template linux logs:log[/var/log/httpd/error_log,,,,,].regexp(MaxClients)}=1 and {Template linux logs:log[/var/log/httpd/error_log,,,,,].nodata(10m)}=0 説明: apacheのプロセスが上限に達しました。
今後
・MySQLなどの設定もデフォルト値のままなので見直す必要がある。
・サイト数が40サイトぐらいあるサーバなのでapacheのログを集計しどのサイトがアクセス数が多いかを把握し対応(サーバ移行など)する必要がある。
「クラウドテック」です。 掲載案件では平均月60万、週3~4日勤務の案件が豊富で生活スタイルに合わせた働き方を設計できます。 また福利厚生が充実し旅行、レジャー、家事代行、ヘビーシッター、健康診断など100種類以上を無料で使えます。
- 97%がリモートのお仕事
- 週4日、週3日OKのお仕事多数
- 登録社数74万件業界トップクラス
- 2〜4週間程度でお仕事決定