rails を graceful restart する方法

graceful restart とは、現在実行中のリクエストを処理し終えてから restart を行うこと。

rails そのものは graceful restart の仕組みを提供していない。fastcgi, mongrel などのコンテナレベルでの仕組みを使うことになる。他のコンテナでのやり方は調べていないが、fastcgi, mongrel ではいずれも USR2 というシグナルを送ることで restart してくれる。中で再度 exec を発行するので ruby プロセスが新たに作られる。そのため使用メモリが一旦リセットされる。

重たい処理をしてメモリが肥大してしまったプロセスなどを定期的に初期化するなどに使うとよい。

以下、方法。

fastcgi で起動している場合
killall -USR2 dispatch.fcgi

mongrel で起動している場合
killall -USR2 mongrel_rails

でいけると思う。

(追記) fcgi の場合、どうも USR2 によって exec しなおした際に、cmd (/proc/PID/cmdの中身)が "ruby dispatch.fcgi" から "ruby" に変わってしまうっぽい。そのため二度目以降 killall dispatch.fcgi としてもシグナルの対象から外れてしまう。
代わりに以下のようにして自前で kill すればよい。

ps aux | grep dispatch.fcgi | sed "s/ \+/ /g" | cut -d' ' -f 2 | xargs killall -USR2