nginxの制御

設定の変更
ログファイルのローテーション
実行ファイルの動的なアップグレード

nginxはシグナルで制御できます。マスタープロセスのプロセスIDは、デフォルトで/usr/local/nginx/logs/nginx.pidファイルに書き込まれます。このファイル名は設定時、またはnginx.confpidディレクティブを使用して変更できます。マスタープロセスは、以下のシグナルに対応しています。

TERM, INT即時シャットダウン
QUIT正常終了
HUP設定の変更、タイムゾーンの変更への対応 (FreeBSDとLinuxのみ)、新しい設定で新しいワーカープロセスの起動、古いワーカープロセスの正常終了
USR1ログファイルの再オープン
USR2実行ファイルのアップグレード
WINCHワーカープロセスの正常終了

個々のワーカープロセスもシグナルで制御できますが、必須ではありません。対応しているシグナルは以下のとおりです。

TERM, INT即時シャットダウン
QUIT正常終了
USR1ログファイルの再オープン
WINCHデバッグのための異常終了 (debug_pointsを有効にする必要があります)

設定の変更

nginxが設定ファイルを再読み込みするには、マスタープロセスにHUPシグナルを送信する必要があります。マスタープロセスはまず構文の有効性をチェックし、次に新しい設定を適用しようとします。つまり、ログファイルと新しいリスニングソケットを開きます。これが失敗した場合、変更をロールバックし、古い設定で動作を続けます。成功した場合、新しいワーカープロセスを起動し、古いワーカープロセスに正常終了を要求するメッセージを送信します。古いワーカープロセスはリスニングソケットを閉じ、古いクライアントへのサービスを続けます。すべてのクライアントへのサービスが完了すると、古いワーカープロセスはシャットダウンされます。

例で説明しましょう。nginxがFreeBSDで実行されており、コマンド

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)

を実行すると、以下の出力が得られるとします。

  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)

(出力は省略) マスタープロセスにHUPを送信すると、出力は次のようになります。

  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)

ログファイルのローテーション

(出力は省略) PID 33129の古いワーカープロセスは1つまだ動作を続けています。しばらくすると、終了します。

実行ファイルの動的なアップグレード

ログファイルをローテーションするには、まずファイル名を変更する必要があります。その後、マスタープロセスにUSR1シグナルを送信する必要があります。マスタープロセスは、現在開いているすべてのログファイルを再オープンし、ワーカープロセスが実行されている非特権ユーザーを所有者として割り当てます。再オープンが成功すると、マスタープロセスはすべての開いているファイルを閉じ、ワーカープロセスにファイルの再オープンを要求するメッセージを送信します。ワーカープロセスも新しいファイルを開き、古いファイルをすぐに閉じます。その結果、古いファイルは圧縮などの後処理にすぐに利用できるようになります。

  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)

サーバーの実行ファイルをアップグレードするには、まず新しい実行ファイルを古いファイルと置き換える必要があります。その後、マスタープロセスにUSR2シグナルを送信する必要があります。マスタープロセスはまず、プロセスIDを持つファイルを.oldbinサフィックスを持つ新しいファイル(例:/usr/local/nginx/logs/nginx.pid.oldbin)に名前変更し、次に新しい実行ファイルを起動します。新しい実行ファイルは、新しいワーカープロセスを起動します。

  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)

その後、すべてのワーカープロセス(古いものと新しいもの)は引き続きリクエストを受け入れます。最初のマスタープロセスにWINCHシグナルが送信されると、ワーカープロセスに正常終了を要求するメッセージが送信され、ワーカープロセスは終了を開始します。

  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)

しばらくすると、新しいワーカープロセスのみがリクエストを処理します。

新しいマスタープロセスにTERMシグナルを送信します。その後、ワーカープロセスにすぐに終了するように要求するメッセージが送信され、ワーカープロセスはほぼすぐに終了します。(何らかの理由で新しいプロセスが終了しない場合は、強制終了するためにKILLシグナルを送信する必要があります。)新しいマスタープロセスが終了すると、古いマスタープロセスは自動的に新しいワーカープロセスを起動します。

新しいマスタープロセスが終了すると、古いマスタープロセスはプロセスIDを持つファイル名から.oldbinサフィックスを削除します。

  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)