はじめに
nginxは頻繁に保守されていてどんどんバージョンが上がっていく一方で、UbuntuやWindows以外ではソースコードからビルドする方法が一般的だと思います。
nginxのバージョンアップ頻度
- 2011/05/10 1.0.2
- 2011/05/03 1.0.1
- 2011/04/12 1.0.0
- 2011/04/04 0.9.7
- 2011/03/21 0.9.6
LinuxやBSDの多くのディストリビューションではNginxがパッケージリポジトリに含まれており、通常のソフトウェアインストール手法でインストールする事ができます。(Debianにおけるapt-getや、Gentooにおけるemerge、FreeBSDにおけるports、Fedora の yum、Vine Linux の apt-get など)
たまにこれらのパッケージは古いものであったりすることがあるので気をつけてください。最新の機能やバグ修正版を求めるなら、ソースコードからビルドすることをお勧めします。…
http://wiki.nginx.org/InstallJaより
上記のようにどのディストリビューションでもパッケージは用意されているものの、バージョンが古いことが多いですし、何よりも各機能を追加するモジュールがApache(httpd)と違ってスタティックな方式を採用しているので、用途に合わせてモジュールを追加したい場合は自分でビルドするしかありません。
そうすると、自分でバイナリを上書きしてアップグレードすることになります。
メンテナンス時間を設けてサービスを止めて保守出来る場合はいいですが、積極的に止めることは避けたいサービスの場合、以下の方法でリクエストを止めることなくアップグレードができます。
今回は、nginx0.7.67を最新版(1.0.2 2011/5/23現在)にアップグレードした時の手順の確認と結果の検証を行いました。
準備
現在稼動しているバージョンのビルドオプションを確認する
-Vオプションで確認することが出来ます。
$ /usr/local/nginx/sbin/nginx -V nginx version: nginx/0.7.67 built by gcc 4.1.2 20080704 (Red Hat 4.1.2-48) TLS SNI support disabled configure arguments: --with-http_stub_status_module --with-http_ssl_module
configure argumentsがオプション部分です。
サードパーティ製のモジュールを入れている場合(–add-module)は、そのモジュールが新しいバージョンのnginxに対応しているか、対応しているモジュールのバージョンがリリースされていないか、確認する必要があります。
最新バージョンをビルドする
先ほど確認したビルドオプションで新しいバージョンをビルドします。
$ wget http://nginx.org/download/nginx-1.0.2.tar.gz $ tar vfxz nginx-1.0.2.tar.gz $ cd nginx-1.0.2 # ここで先のオプションを使う $ ./configure --with-http_stub_status_module --with-http_ssl_module $ make # 成功すると./objs 以下に新しいバイナリが出来上がるので確認 $ ./objs/nginx -V nginx: nginx version: nginx/1.0.2 nginx: built by gcc 4.1.2 20080704 (Red Hat 4.1.2-50) nginx: TLS SNI support disabled nginx: configure arguments: --with-http_stub_status_module --with-http_ssl_module
現行の設定ファイルのままで問題がないか確認する
仕様の変更などで利用できなくなるディレクティブなどがあるかもしれません。現行の設定ファイルでconfig testが通るかチェックします。
$ sudo ./objs/nginx -t -c /usr/local/nginx/conf/nginx.conf 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
アップグレード
バイナリをコピーする
単純にコピーnginxファイルを上書きするか、make installで上書きします。
$ sudo cp objs/nginx /usr/local/nginx/sbin/nginx
or
$ sudo make install
プロセスを確認する
いよいよ本題です。現在動いているnginxのマスタープロセスのpidを確認します。
psコマンド確認する方法
$ ps aux |grep nginx root 5559 0.0 0.0 40976 1000 ? Ss 16:36 0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf nginx 5560 0.0 0.2 42572 3052 ? S 16:36 0:00 nginx: worker process nginx 5561 0.0 0.2 42572 3044 ? S 16:36 0:00 nginx: worker process nginx 5562 0.0 0.2 42572 2992 ? S 16:36 0:00 nginx: worker process nginx 5564 0.0 0.2 42572 2940 ? S 16:36 0:00 nginx: worker process
pidファイルで確認する方法
nginx.confにpidディレクティブを設定している場合は設定したパスにpidファイルがあります。
$ cat /var/run/nginx.pid; 5559
pidは5559です。
ワーカープロセス数は、confファイル"worker_processes"の設定に依存します。
新しいバイナリを実行する(USR2シグナル)
USR2シグナルをマスタープロセスに送ります。
$ sudo kill -USR2 5559
すると、古いバージョンのプロセスと新しいバージョンのプロセスが共存する状態になります。
$ ps aux |grep nginx root 5559 0.0 0.0 40976 1068 ? Ss 16:36 0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf nginx 5560 0.0 0.2 42572 3052 ? S 16:36 0:00 nginx: worker process nginx 5561 0.0 0.2 42572 3044 ? S 16:36 0:00 nginx: worker process nginx 5562 0.0 0.2 42572 2992 ? S 16:36 0:00 nginx: worker process nginx 5564 0.0 0.2 42572 2940 ? S 16:36 0:00 nginx: worker process root 7962 2.0 0.2 41024 3084 ? S 19:29 0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf nginx 7963 0.0 0.2 42732 3060 ? S 19:29 0:00 nginx: worker process nginx 7964 0.0 0.2 42732 2860 ? S 19:29 0:00 nginx: worker process nginx 7965 0.0 0.2 42732 2860 ? S 19:29 0:00 nginx: worker process nginx 7966 0.0 0.2 42732 2852 ? S 19:29 0:00 nginx: worker process
古いバージョンのワーカーを止める(WINCHシグナル)
WINCHシグナルを古いマスタープロセスに送ります。
$ sudo kill -WINCH 5559
すると、既に受け持っているリクエストの処理が終わり次第、古いワーカープロセスが順次終了していきます。古いプロセスはマスタープロセスだけになり、リクエストは新しいワーカープロセスが受け持っています。
ps aux |grep nginx root 5559 0.0 0.0 40976 1072 ? Ss 16:36 0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf root 7962 0.0 0.2 41024 3084 ? S 19:29 0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf nginx 7963 0.0 0.2 42732 3060 ? S 19:29 0:00 nginx: worker process nginx 7964 0.0 0.2 42732 2860 ? S 19:29 0:00 nginx: worker process nginx 7965 0.0 0.2 42732 2860 ? S 19:29 0:00 nginx: worker process nginx 7966 0.0 0.2 42732 2852 ? S 19:29 0:00 nginx: worker process
古いバージョンのマスタープロセスを止める(QUITシグナル)
QUITシグナルを古いマスタープロセスに送ります。
$ sudo kill -QUIT 5559
古いマスタープロセスが終了し、新しいマスタープロセスとワーカープロセスだけになりました。
$ ps aux |grep nginx root 7962 0.0 0.2 41024 3084 ? S 19:29 0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf nginx 7963 0.0 0.2 42732 3060 ? S 19:29 0:00 nginx: worker process nginx 7964 0.0 0.2 42732 2860 ? S 19:29 0:00 nginx: worker process nginx 7965 0.0 0.2 42732 2860 ? S 19:29 0:00 nginx: worker process nginx 7966 0.0 0.2 42732 2852 ? S 19:29 0:00 nginx: worker process
検証
検証方法
http_loadを使ってドキュメントルートに置いたテキストファイルをアップグレード作業中にクライアントから毎秒10リクエスト行う。
結果
作業中の2分間、1199リクエストが全て正常に終了したので、問題なくアップグレードができたと思われます。
./http_load -rate 10 -seconds 120 -verbose url_file --- 60.0062 secs, 600 fetches started, 599 completed, 1 current --- 120.006 secs, 1200 fetches started, 1199 completed, 1 current 1199 fetches, 1 max parallel, 3597 bytes, in 120.006 seconds 3 mean bytes/connection 9.99115 fetches/sec, 29.9735 bytes/sec msecs/connect: 0.417418 mean, 0.717 max, 0.248 min msecs/first-response: 0.353556 mean, 0.605 max, 0.253 min HTTP response codes: code 200 -- 1199
シェアさせていただきます。良い記事ありがとうございます。
[…] cloudropさんの記事を参考にさせていただきました。 […]
[…] た後に下記の方の記事を参考にすると幸せになれるでしょう リクエストを落とさずにnginxをアップグレードする方法とその検証 __spr_config = { pid: '4f0d867e396cef08a60000e7', title: 'Nginx アップデ […]
[…] リクエストを落とさずにnginxをアップグレードする方法とその検証 […]
[…] リクエストを落とさずにnginxをアップグレードする方法とその検証 […]