LoginSignup
15
10

More than 5 years have passed since last update.

無停止でnginxを手動upgradeする

Last updated at Posted at 2016-02-03

無停止でnginxのupgradeを行う手順

無停止でnginxを新しいバージョンへアップグレードする手順です。

だいたいここに書いてあります。
http://nginx.org/en/docs/control.html#upgrade

作業内容

nginx 1.7.3 -> 1.9.9 へアップグレード

環境

  • OS
    CentOS 6.6
  • nginx1.7.3が起動している
    nginx.confなどがすでに存在
    nginx1.7.3 は ソースからインストールされている(/usr/local/nginx/以下)
  • php-fpm等は起動していない

作業はすべてrootユーザで実施します

kill/make install等でsudoが必要な場合があります。
rootユーザで実施するためその辺りは考慮していません。

nginx 1.9.9 のバイナリの用意

configureオプションは適当に。

# wget http://nginx.org/download/nginx-1.9.9.tar.gz
# tar zxf nginx-1.9.9.tar.gz
# cd nginx-1.9.9 ; pwd
# ./configure
# make
# make install

この状態では、まだアップグレードされていません。

# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.7.3

この状態でmake upgradeすると自動で置き換わります。
すごいですね。

アップグレード手順

最初に手順だけをあげると下記となります。

# /usr/local/nginx/sbin/nginx -t
# kill -USR2 `cat /usr/local/nginx/logs/nginx.pid`
# kill -WINCH `cat /usr/local/nginx/logs/nginx.pid.oldbin`
# kill -QUIT `cat /usr/local/nginx/logs/nginx.pid.oldbin`
# /usr/local/nginx/sbin/nginx -V

挙動を見ていきます

  • アップグレード前の状態
    masterプロセスのpidは4388です。
# ps auxww | grep 'nginx'
root      4388  0.1  0.3 105792  6304 ?        S    02:29   0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/ngin /etc/nginx.conf
nginx     4389  0.0  0.1 106228  2836 ?        S    02:29   0:00 nginx: worker process
nginx     4390  0.0  0.1 106228  2904 ?        S    02:29   0:00 nginx: worker process
nginx     4391  0.0  0.1 106228  2884 ?        S    02:29   0:00 nginx: worker process
root      4397  0.0  0.0   6388   680 pts/2    S+   02:29   0:00 grep --color=auto nginx
#

1.config test

# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
#

2.USR2シグナル送信

  • 新しいバイナリのnginxプロセスが起動
  • アップグレード前nginxのpidファイルがnginx.pid.oldbinとなる
  • アップグレード後のnginxが処理を開始
# kill -USR2 `cat /usr/local/nginx/logs/nginx.pid`
# ps auxwwf | grep 'ngin[x]'
root      4388  0.0  0.3 105792  6304 ?        S    02:29   0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/ngin /etc/nginx.conf
nginx     4389  0.0  0.1 106228  2836 ?        S    02:29   0:00  \_ nginx: worker process
nginx     4390  0.0  0.1 106228  2904 ?        S    02:29   0:00  \_ nginx: worker process
nginx     4391  0.0  0.1 106228  2884 ?        S    02:29   0:00  \_ nginx: worker process
root      4464  0.0  0.3 103516  6240 ?        S    02:31   0:00  \_ nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/etc/nginx.conf
nginx     4465  0.0  0.1 103944  2828 ?        S    02:31   0:00      \_ nginx: worker process                                        
nginx     4466  0.0  0.1 103944  2896 ?        S    02:31   0:00      \_ nginx: worker process                                        
nginx     4467  0.0  0.1 103944  2872 ?        S    02:31   0:00      \_ nginx: worker process                                        
#
#
# ls -la /usr/local/nginx/logs/nginx.pid*
-rw-r--r-- 1 root  root         5 Feb  4 02:31 nginx.pid
-rw-r--r-- 1 root  root         5 Feb  4 02:29 nginx.pid.oldbin
#

アップグレード後nginxのmasterプロセスが起動しています。pid4464のものになります。
アップグレード前nginxのmasterプロセス4388の方も起動しているのが分かります。

USR2を送ると

  • アップグレード後masterプロセスとアップグレード前masterプロセスが混在する事に
  • アップグレード後nginxのpid -> nginx.pid
  • アップグレード前nginxのpid -> nginx.pid.oldbin

以降、nginx.pid.oldbinへシグナルを送信することでアップグレード前nginxを、
nginx.pidへシグナルを送る事でアップグレード後nginxを操作できます。

3.WINCHシグナルの送信

  • アップグレード前masterプロセスがworkerプロセスを終了し、アップグレード後のnginxのみで処理を開始
# kill -WINCH `cat /usr/local/nginx/logs/nginx.pid.oldbin`
#
# ps auxwwf | grep 'ngin[x]'
root      4388  0.0  0.3 105792  6304 ?        S    02:29   0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/ngin /etc/nginx.conf
root      4464  0.0  0.3 103516  6240 ?        S    02:31   0:00  \_ nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/etc/nginx.conf
nginx     4465  0.0  0.1 103944  2828 ?        S    02:31   0:00      \_ nginx: worker process                                        
nginx     4466  0.0  0.1 103944  2896 ?        S    02:31   0:00      \_ nginx: worker process                                        
nginx     4467  0.0  0.1 103944  2872 ?        S    02:31   0:00      \_ nginx: worker process                                        
#

アップグレード前masterプロセスであるpid4388が存在し、workerプロセスが無くなっています。

WINCHシグナルを送ると

アップグレード前masterプロセスが管理下にあるworkerプロセスを終了させます。
この状態では、すべてのリクエストを新しいnginxが処理することになります。
この状態で、Web閲覧が不可能等である場合は切り戻す事になります。
切り戻し手順は後述します。

4.QUITシグナルをアップグレード前nginxに送信

  • アップグレード前nginxのマスタープロセスが完全に終了
# kill -QUIT `cat /usr/local/nginx/logs/nginx.pid.oldbin`
# ps auxwwf | grep 'ngin[x]'
root      4464  0.0  0.3 103516  6240 ?        S    02:31   0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/ngin /etc/nginx.conf
nginx     4465  0.0  0.1 103944  2828 ?        S    02:31   0:00  \_ nginx: worker process
nginx     4466  0.0  0.1 103944  2896 ?        S    02:31   0:00  \_ nginx: worker process
nginx     4467  0.0  0.1 103944  2872 ?        S    02:31   0:00  \_ nginx: worker process
#
# ls -l /usr/local/nginx/logs/nginx.pid
-rw-r--r-- 1 root root 5 Feb  4 02:31 /usr/local/nginx/logs/nginx.pid
#
#
# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.9.9
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-11) (GCC)
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
#

アップグレード前のmasterプロセスが完全に終了しています。
これでアップグレードは完了となります。

切り戻し手段

途中で問題が発生した場合は切り戻す事になります。方法は2つです。

  • アップグレード前masterプロセスへHUPシグナルを送信
    アップグレード後masterプロセスを終了し、アップグレード前masterプロセスがworkerプロセスを作成します。

  • アップグレード後TERMシグナルを送信
    アップグレード前masterプロセスがアップグレード後masterプロセスの終了を検知すると、workerプロセスを作成します。

# kill -s HUP `cat /usr/local/nginx/logs/nginx.pid.oldbin`
15
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
10