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] を記録してまたエントリで報告します。