T

Apacheの救急救助手順

最近Apacheの設定なんか知らないという人が増えたのでメモ。急にアクセス数が増えてサーバのロードアベレージが跳ね上がり、レスポンスが返らなくなったサーバについて質問されたとき、どこをどう確認するか、いつもあまり考えずにやってることを記録する。専門ってわけじゃないので、応急処置として何をしているのか見る感じ。対処法はそれぞれのシステムで違うだろうけど。

Apacheのログを見られるなら、それを最初に確認する。意外なことにディスク容量が足りなくて動かなくなっていたり、ファイルシステムの上限設定に引っかかっていて動かないケースも結構あるのだ。それから、セマフォキューが書き込めなくなっていることもあるが、これが一番見つかり難い。Apacheのエラーログに

[emerg] (28)No space left on device: Couldn't create accept lock

こんなのが出ているのにディスクの残り容量やクォータに問題がなければ、セマフォの問題なのでクリアしないといけない。

// rootで
# for i in `ipcs -s | awk '/httpd/ {print $2}'`; do (ipcrm -s $i); done

手慣れたサーバ管理者なら、こんな感じのワンライナーをどこかに保存してあるはずだ。ここを参考にした記憶がある。

MuninやNagiosなどで監視しているなら、最初に必ず確認しよう。証拠も無しにあれこれ手を出したり推測で動き出すのは愚か者に特有の対応だ。もちろんサーバがレスポンスを返せないような状態になったら何の情報も取れなくなっているだろうが、たとえそうであっても、そうなるに至るまでの過程は見える。Apacheのウェブサーバで提供しているサービスなら、たいていCPUが原因で死ぬことはないので、I/O waitとかSWAPの発生、メモリの使用状況とかを真っ先に見る。別に難しい理屈はない。I/O waitが伸びていてSWAPが発生していれば、メモリの使用状況もひどいことになっているはずなので、それらが一致していれば、ああApacheに割り当てられたリソースをシステム側で供給維持しきれなくなって暴動が起きたんだなと理解できる。PHPなんかが動いているpreforkのApacheなら、プロセス数がMaxClientsまで達したかどうかを見るといいかもしれない。達していれば単純に性能の限界だったんだろう。その前にコケていたなら、設定が間違っている。まあ、あんまりきちんと設定されていないサーバでは、大概は達する前にコケている。そんなときは、とりあえずApacheがどれくらいメモリを食うのか調べてみるのも一興。

$ ps ax | grep httpd | grep -v grep | awk '{print $1}' | while read pid
do
cat /proc/$pid/status | grep VmHWM
done

ひゃっほう、Apacheのプロセスたちが物理メモリをピーク時にどれだけ使ったか表示される。これらの数値を見て、まあ大きい方のやつがApacheのMaxClientsの分だけ起動したらどうなるかかけ算すれば、リソースをApacheに食い尽くされないMaxClientsの設定値が見えてくるはずだ。80MBのプロセスがいるなら、まあみんなが最大値になってしまうことはないけれど、そいつをシステムの物理メモリで割った値にちょっと手加減するくらいならなんとかなると見当がつくだろう。

上のやつだとkB単位で個々に結果が表示されるので、どうせなら一気にその合計まで出そう。

$ ps ax | grep httpd | grep -v grep | awk '{print $1}' | while read pid
do
cat /proc/$pid/status | grep VmHWM
done | awk '{sum += $2} END {print sum}'

手元のサーバで実行したら642964だった。kBだから640MB程度。まだまだ大丈夫そうだ。

他にも、サーバに運良くログインできれば、例えばvmstatやsarを実行してみる。

$ vmstat 1
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0 307012 212128 118136 2375840    1    1    23   103    8    9 10  2 88  0  0
 1  0 307012 210656 118148 2375848    0    0     4   136  694  606  3  1 97  1  0
 0  0 307012 211416 118152 2375852    0    0     0   124  589  478  4  0 95  0  0
 0  0 307012 206736 118152 2375880    0    0     4    12  785  630  5  1 93  0  0
 0  0 307012 214992 118152 2375888    0    0     8     0  429  297  1  1 98  0  0
 0  0 307012 208428 118152 2375908    0    0     0   168  506  694 22  2 76  0  0
 0  0 307012 211900 118152 2375920    0    0     0   168  809  614  7  3 90  0  0
.......

$ sar 
(略)
10時00分01秒       CPU     %user     %nice   %system   %iowait    %steal     %idle
10時10分01秒       all     10.96      0.20      2.01      0.25      0.02     86.57
10時20分01秒       all     11.01      0.27      1.92      0.36      0.02     86.42
10時30分01秒       all     11.55      0.23      2.11      0.32      0.02     85.77
10時40分01秒       all     11.27      0.20      1.86      0.21      0.02     86.44
10時50分01秒       all     11.05      0.38      1.73      0.22      0.02     86.61
11時00分01秒       all      7.74      0.20      1.55      0.14      0.02     90.35
11時10分01秒       all     10.51      0.21      2.31      0.34      0.02     86.61
平均値:        all      9.86      0.24      1.58      0.39      0.02     87.90

上は一時的に死にかけたけど健康を取り戻しつつあるサーバの例。vmstatのswapの欄で頻繁にsiとかsoが出ていたり、swpdの値が増え続けているなら非常にまずい状態だ。ApacheのMaxClientsを下げてでもリソース消費を抑えないとサーバにログインさえできなくなるかもしれない。OOM Killerに大事な身内を殺される前になんとかしないといけない。またsarでiowaitの増減を確認すると問題の起きる時間帯がうまく特定できる。

娘が自らオムツを外して床におしっことうんこをするというチャレンジに成功したので、掃除や着替えに忙しく中断していたら、何を書こうとしていたのか思い出せない。ええと、最近のクラウンド環境とかだと、物理サーバの頃よりますますI/O性能に引っ張られてしまう傾向にあるから、まずはこれらの確認が大事になる。

それから、忘れてはいけないのがserver-statusで、SSHでトンネル掘ってでも見に行くべきだ。レスポンスが遅くなっているページがあればすぐに見つかるし、例えばApacheからImageMagickのプロセスを呼んでそのまま刺さりっぱなしになっているリクエストなどが見つかり、そいつがプロセスを占有しているのが問題の原因だったりすることもある。それから、現在のスロット(preforkだったら各プロセス)のステータスがリアルタイムで表示されるのも面白い。

CC__.WWCC..WCK.KKKKW..WWKKW.....................................
................................................................

例えば、Kはデータの送出が終わってもKeepAliveで一応待っている状態のやつ、Wがデータを送出中、Cは接続終了処理中で、「.」は接続を待ち受けているやつだ。もしレスポンスが悪くて困っているなら、場合によってはいっそKeepAliveを切ってしまってもいいだろう。感覚としては、PC向けのサービスで帯域の利用状況が問題になってはいないケースなら切ってしまうことの方が多い。

とりあえず、初動としてはまずはこんな感じの対応をする。いずれも安定稼働しているサーバのメンテでやっていることなので、それ以外は別の対処があるだろうし、アプリケーション側で出来ることもたくさんあるが、夜中の連絡で緊急出動する場合はそこまでやっていられないだろう。

Posted by on 2月 11, 2013 in Apache, Linux

コメントを残す