unicornを無停止で再起動(新しい設定をリロード) すなわちgraceful restartさせるのにはマスタープロセスに対して kill -s USR2
すると薄ら理解していたのですが、そのためにはきちんと設定がいるのでその際の対応と、実際に行った際に観察したプロセスをメモしておきます。
まず、設定しているunicorn.confには以下の設定を記載しておきます。
よく参照されているunicorn.conf.rb の中でコメントアウトされている辺りを有効にする必要があります。
また、リスタート時にGemfileのパスを強制的に指定させる様にしているのは、graceful restartさせた後に新しいGemfileの更新を適用させるためです。
上の記述がある状態でunicornを起動していれば、USR2シグナルをmasterのプロセスに送るとgraceful restartできます。
試しに手動でプロセスをkillしてみます。まずは現状を確認。masterのプロセスは7864であることが確認できます。
remper 7864 66.2 7.1 320460 72732 ? Sl 23:11 0:05 unicorn master -c config/unicorn.conf -E production -D remper 7876 0.0 6.7 320460 69156 ? Sl 23:11 0:00 unicorn worker[0] -c config/unicorn.conf -E production -D remper 7880 0.0 6.7 320460 69148 ? Sl 23:11 0:00 unicorn worker[1] -c config/unicorn.conf -E production -D
この状態から、master processをkillしてみます。
$ kill -s USR2 (unicorn master processのPID, ここでは7864)
とすると、現行のmasterが新しいmasterをforkします。
(下のプロセス一覧だと7908というPIDが該当)
remper 7864 15.2 7.1 320460 72900 ? Sl 23:11 0:05 unicorn master (old) -c config/unicorn.conf -E production -D remper 7876 0.0 6.8 321488 69744 ? Sl 23:11 0:00 unicorn worker[0] -c config/unicorn.conf -E production -D remper 7880 1.2 7.0 320896 71576 ? Sl 23:11 0:00 unicorn worker[1] -c config/unicorn.conf -E production -D remper 7908 57.0 2.2 84032 23164 ? Rl 23:11 0:00 ruby /〜/releases/11/vendor/bundle/ruby/1.9.1/bin/unicorn -c config/unicorn.conf -E production -D
そして、いままでのmasterから生えていたworkerが無くなって、新しいworkerが新しいmasterから生えてきます。
下の一覧だと unicorn worker[(0|1)] というプロセスのPIDが上のPID一覧のものと換わっているのがわかります。
remper 7908 44.6 7.1 320580 72736 ? Sl 23:11 0:05 unicorn master -c config/unicorn.conf -E production -D remper 7922 0.0 6.7 320580 69116 ? Sl 23:11 0:00 unicorn worker[0] -c config/unicorn.conf -E production -D remper 7926 0.1 6.7 320580 69112 ? Sl 23:11 0:00 unicorn worker[1] -c config/unicorn.conf -E production -D
ということで、unicorn.confに適切な設定を記載することでgraceful restartさせることができました。
そして、もろもろこの辺り調べていると大抵私が所属しているペパボのエンジニアの方のブログにぶつかって便利。そして感謝。
参照
Unicornのgraceful restartで少しハマった件 - blog.tnmt.info
追伸
はてなブログから移設した際にgraceful restartのスクリプト例が崩れていたのでgistで貼り直しました。