Server::Starter + Starman で HUP 再起動が上手くいかないことがある
現在、Server::Starter + Starman で運用している環境があるのですが、週に1回ほど古いワーカーが終了しないで残り続けるという現象が起こっています。
FCGI 起動の名残りで、毎時間 HUP を投げていたのですが、普段は問題なく starman プロセスが再起動していたのですが、たまに再起動が上手く行かずに、古いプロセスが残り、リクエストに応答できなくなるという状態です。
start_server の起動オプションは以下です。
start_server --port 8001 -- starman --listen :8001 --workers 4 app.psgi
現象が起こっている時の ps 結果
$ pgrep -f starman | xargs ps u USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND **** 2115 0.2 2.1 41272 37436 ? S 11:00 0:02 starman worker --listen :8001 --workers 4 app.psgi **** 2116 0.2 2.1 41276 37436 ? S 11:00 0:02 starman worker --listen :8001 --workers 4 app.psgi **** 2117 0.2 2.1 41260 37436 ? S 11:00 0:01 starman worker --listen :8001 --workers 4 app.psgi **** 25738 0.1 2.5 50184 44912 ? S 10:00 0:07 starman worker --listen :8001 --workers 4 app.psgi **** 25745 0.1 2.5 50188 44916 ? S 10:00 0:06 starman worker --listen :8001 --workers 4 app.psgi **** 25747 0.1 2.5 50168 44896 ? S 10:00 0:06 starman worker --listen :8001 --workers 4 app.psgi **** 25749 0.1 2.5 50196 44976 ? S 10:00 0:06 starman worker --listen :8001 --workers 4 app.psgi
使用バージョン
OS: Ubuntu 9.04 perl: 5.10.0 Starman: 0.2004 Server::Starter: 0.07
この問題に関して、IRC で質問して以下のようなアドバイスをいただけました。
- start_server は HUP を受け取ると、次のワーカーを起動し、sleep(inteval) してから古いワーカーに TERM を送るので、後は TERM を受け取って、古いワーカーがちゃんと終了するかしないかの問題
- accept(2) が SIGTERM 受け取っても戻らないのかなぁ
- /proc/[pid]/fd/ をチェックしてみると良いかも Manpage of PROC
- 落ちない古いプロセスに対して、strace -p [pid] でもなんかわかるかなぁ
- メモリリークが心配なら HUP ではなく、starman の --max-requests の調整で対応する。とりあえずデフォルトの 1000 で問題あれば上げたり下げたり。
- start_server の --interval は大切
とりあえず 定期 HUP やめてみるのと、次回また起こった時に、/proc/[pid]/fd と strace -p [pid] を記録してまたエントリで報告します。