nginxのコントロール
設定の変更 ログファイルのローテート その場でのアップグレード |
nginxはシグナルで制御できます。マスタープロセスのプロセスIDはデフォルトでは/usr/local/nginx/logs/nginx.pid
ファイルに書かれています。この名前は設定時に変更されているかも知れません。pidディレクティブを使ってnginx.conf
にあります。マスタープロセスは次のシグナルをサポートしています:
TERM, INT 高速なシャットダウン QUIT グレースフル シャットダウン HUP 設定の変更、タイムゾーンの変更への追随(FreeBSDとLinuxのみ)、新しい設定での新しいworkerプロセスの開始、古いworkerプロセスのグレースフルシャットダウン USR1 ログファイルの開き直し USR2 実行ファイルのアップグレード WINCH workerプロセスのグレースフルシャットダウン
必要ないでしょうが、個々のworkerプロセスも同じようにシグナルで制御することができます。サポートされているシグナルは以下の通りです:
TERM, INT 高速なシャットダウン QUIT グレースフル シャットダウン USR1 ログファイルの開き直し WINCH デバッグのための異常停止(debug_pointsが有効になっている事が必要です)
設定の変更
nginxが設定ファイルを再読込みするには、HUPシグナルがマスタープロセスに送られる必要があります。マスタープロセスはまず文法的な検証をチェックし、それから新しい設定を適用しようとします。つまり、ログファイルと新しいlistenソケットを開こうとします。もし失敗すれば、変更を巻き返し、古い設定で動作し続けます。成功した場合は、新しいworkerプロセスを開始し、古いworkerプロセスにグレースフルにシャットダウンするようにメッセージを送信します。. 古いworkerプロセスはlistenソケットを閉じ、古いクライアントへの提供を続けます。全てのクライアントへの提供が終了した後で、古いworkerプロセスはシャットダウンされます。
例を使ってこれを説明しましょう。Imagine that nginx is run on FreeBSD and the command
ps axw -o pid,ppid,user,%cpu,vsz,wchan,command | egrep '(nginx|PID)'
次の出力が生成されます:
PID PPID USER %CPU VSZ WCHAN COMMAND 33126 1 root 0.0 1148 pause nginx: master process /usr/local/nginx/sbin/nginx 33127 33126 nobody 0.0 1380 kqread nginx: worker process (nginx) 33128 33126 nobody 0.0 1364 kqread nginx: worker process (nginx) 33129 33126 nobody 0.0 1364 kqread nginx: worker process (nginx)
HUPがマスタープロセスに送られると、出力は次のようになります:
PID PPID USER %CPU VSZ WCHAN COMMAND 33126 1 root 0.0 1164 pause nginx: master process /usr/local/nginx/sbin/nginx 33129 33126 nobody 0.0 1380 kqread nginx: worker process is shutting down (nginx) 33134 33126 nobody 0.0 1368 kqread nginx: worker process (nginx) 33135 33126 nobody 0.0 1368 kqread nginx: worker process (nginx) 33136 33126 nobody 0.0 1368 kqread nginx: worker process (nginx)
PID 33129 の古いworkerプロセスのうちの一つがまだ動作しています。しばらくすると、終了します:
PID PPID USER %CPU VSZ WCHAN COMMAND 33126 1 root 0.0 1164 pause nginx: master process /usr/local/nginx/sbin/nginx 33134 33126 nobody 0.0 1368 kqread nginx: worker process (nginx) 33135 33126 nobody 0.0 1368 kqread nginx: worker process (nginx) 33136 33126 nobody 0.0 1368 kqread nginx: worker process (nginx)
ログファイルのローテート
ログをローテートするには、まずそれらをリネームする必要があります。それから、マスタープロセスにUSR1シグナルが送信されなければなりません。マスタープロセスは現在開かれている全てのログファイルを開き直し、workerプロセスを実行している特権の無いユーザをオーナーとして割り当てます。開き直しが成功した後で、マスタープロセスは全ての開かれているファイルを閉じ、workerプロセスにファイルを開き直すように要求します。workerプロセスもすぐに新しいファイルを開き古いファイルを閉じます。結果として、古いファイルはほとんど即座に圧縮などの次の処理に利用可能になります。
その場でのアップグレード
サーバの実行ファイルをアップグレードするには、まず新しい実行ファイルが古いファイルの場所に配置されなければなりません。それから、USR2シグナルがマスタープロセスに送信されなければなりません。マスタープロセスはまずそれらのファイルをプロセスIDを使って.oldbin
サフィックスが付いた新しいファイルにリネームします。例えば /usr/local/nginx/logs/nginx.pid.oldbin
。それから、今度は新しいworkerプロセスを開始する新しい実行ファイルを開始します:
PID PPID USER %CPU VSZ WCHAN COMMAND 33126 1 root 0.0 1164 pause nginx: master process /usr/local/nginx/sbin/nginx 33134 33126 nobody 0.0 1368 kqread nginx: worker process (nginx) 33135 33126 nobody 0.0 1380 kqread nginx: worker process (nginx) 33136 33126 nobody 0.0 1368 kqread nginx: worker process (nginx) 36264 33126 root 0.0 1148 pause nginx: master process /usr/local/nginx/sbin/nginx 36265 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) 36266 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) 36267 36264 nobody 0.0 1364 kqread nginx: worker process (nginx)
その後、全てのworkerプロセス(古いものと新しいもの)は、リクエストを受け続けます。最初のマスタープロセスにWINCHシグナルが送られた場合は、マスタープロセスはworkerプロセスにグレースフルにシャットダウンするように要求し、workerプロセスは終了を開始するでしょう。
PID PPID USER %CPU VSZ WCHAN COMMAND 33126 1 root 0.0 1164 pause nginx: master process /usr/local/nginx/sbin/nginx 33135 33126 nobody 0.0 1380 kqread nginx: worker process is shutting down (nginx) 36264 33126 root 0.0 1148 pause nginx: master process /usr/local/nginx/sbin/nginx 36265 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) 36266 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) 36267 36264 nobody 0.0 1364 kqread nginx: worker process (nginx)
しばらくすると、新しいプロセスだけがリクエストを処理するでしょう。:
PID PPID USER %CPU VSZ WCHAN COMMAND 33126 1 root 0.0 1164 pause nginx: master process /usr/local/nginx/sbin/nginx 36264 33126 root 0.0 1148 pause nginx: master process /usr/local/nginx/sbin/nginx 36265 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) 36266 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) 36267 36264 nobody 0.0 1364 kqread nginx: worker process (nginx)
古いマスタープロセスはlistenソケットを閉じず、必要であればworkerプロセスを再びなんとか開始できることに気を付けなければなりません。もし新しい実行ファイルが受け付けをしないなんらかの理由があれば、次のどれかをすることができます:
-
古いマスタープロセスにHUPシグナルを送信する。古いマスタープロセスは設定を再読込みせずに新しいworkerプロセスを開始するでしょう。その後、新しいマスタープロセスにQUITシグナルを送信することで、全ての新しいプロセスはグレースフルにシャットダウンすることができます。
-
新しいマスタープロセスにTERMシグナルを送信する。新しいマスタープロセスはworkerプロセスにすぐに終了するように要求するメッセージを送信し、workerプロセスはほぼ即座に終了するでしょう。(もし新しいプロセスがなんからの理由で終了しないならば、強制的に終了するようにKILLシグナルが送信されるべきです。)新しいマスタープロセスが終了した時に古いマスタープロセスが自動的に新しいworkerプロセスを開始するでしょう。
新しいマスタープロセスが終了すると、古いマスタプロセスはファイル名からプロセスID付きの.oldbin
サフィックスを削除します。
アップグレードが成功した場合、QUITシグナルは古いマスタプロセスに送信され、新しいプロセスだけが残るようにする必要があります:
PID PPID USER %CPU VSZ WCHAN COMMAND 36264 1 root 0.0 1148 pause nginx: master process /usr/local/nginx/sbin/nginx 36265 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) 36266 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) 36267 36264 nobody 0.0 1364 kqread nginx: worker process (nginx)