nginx编译安装后对nginx进行平滑升级

前言

nginx编译安装后用了一段时间后发现当前版本太老或需要新的功能时就需对当前nginx版本进行版本升级,但又不能影响正常的使用,所以这时就需到对nginx的平滑升级,更新到最新版本了。

本文演示的是nginx-1.6.0升级到nginx-1.14.0的过程,其他版本也适用。

基础知识点

官方文档参考:http://nginx.org/en/docs/control.html#upgrade
nginx允许我们通过向她发送信号来控制nginx。nginx的主进程号一般写在 /usr/local/nginx/logs/nginx.pid(即nginx运行时的日志目录下的nginx.pid)。nginx主进程支持以下信号:

信号执行内容
TERM, INTfast shutdown (快速停止,相当于nginx -s stop )
QUITgraceful shutdown (优雅的停止,处理完已经接受的请求, 相当于nginx -s quit)
HUPchanging configuration, keeping up with a changed time zone (only for FreeBSD and Linux), starting new worker processes with a new configuration, graceful shutdown of old worker processes 更改配置,以新的配置文件开启新的worker进程,并优雅的关闭老的worker进程,相当于 nginx -s reload
USR1re-opening log files (重新打开日志文件, 相当于nginx -s reopen )
USR2upgrading an executable file (升级可执行文件)
WINCHgraceful shutdown of worker processes (优雅地关闭worker进程)

nginx新版的下载

下载页面:http://nginx.org/en/download.html

1
wget http://nginx.org/download/nginx-1.14.0.tar.gz

获取老版本nginx的配置

查看当前版本:/usr/local/nginx/sbin/nginx -v
查看当前配置:/usr/local/nginx/sbin/nginx -V

1
2
3
4
5
6
7
[root@linuxboy ~]# /usr/local/nginx/sbin/nginx -v
nginx version: nginx/1.6.0
[root@linuxboy ~]# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.6.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC)
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx-1.14.0 --without-http_memcached_module --user=www --group=www --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-openssl --with-pcre

解压新版nginx源码包

1
2
tar xf nginx-1.14.0.tar.gz 
cd nginx-1.14.0

对新版重新编译前的配置

这里的配置和老版本的一样 : /usr/local/nginx/sbin/nginx -V

1
./configure --prefix=/usr/local/nginx-1.6.0 --without-http_memcached_module --user=www --group=www --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-openssl --with-pcre

执行echo $?来判断是否安装重新编译成功。

编译

只编译make ,不执行make install

编译后通过ls可以看到有个objs的目录

1
2
3
[root@linuxboy nginx-1.14.0]# ls
auto CHANGES.ru configure html Makefile objs src
CHANGES conf contrib LICENSE man README

进入objs目录,替换老版本的nginx主程序(在操作这里前一定要先备份,免得出错)

1
2
3
4
# 备份二进制执行文件
cp -a /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
# 将新编译的二进制文件拷贝到现有nginx目录下
cp -r /server/tools/nginx-1.14.0/objs/nginx /usr/local/nginx/sbin/nginx

平滑升级

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
make upgrade
# 检查nginx是否正常
/usr/local/nginx-1.6.0/sbin/nginx -t
nginx: the configuration file /usr/local/nginx-1.6.0/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx-1.6.0/conf/nginx.conf test is successful
# 给nginx的master进程发送升级信号
kill -USR2 `cat /usr/local/nginx-1.6.0/logs/nginx.pid`
#向老nginx进程发送一个信号:WINCH 让其优雅关闭所有的worker进程
kill -WINCH `cat /usr/local/nginx-1.6.0/logs/nginx.pid`
此时所有的请求都会平滑过渡到新的worker进程。但是旧的master进程还在
只是没有worker进程,如果要回退,只需要拉回旧的nginx拉回worker进程。如果运行一段时间没有问题,可以通过kill -QUIT 彻底关闭老进程

回滚:
kill -HUP 13195 #拉回原来的nginx进程 (kill -HUP 和 -SIGHUP 作用是一样的)
kill -QUIT 18034#关闭新起的master进程,该master进程会通知它下面的worker进程关闭

test -f /usr/local/nginx-1.6.0/logs/nginx.pid.oldbin
kill -QUIT `cat /usr/local/nginx-1.6.0/logs/nginx.pid.oldbin`

升级成功,查看版本

1
2
3
4
5
6
7
8
9
[root@linuxboy ~]# /usr/local/nginx/sbin/nginx -v
nginx version: nginx/1.14.0

[root@linuxboy ~]# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.14.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC)
built with OpenSSL 1.0.1h 5 Jun 2014
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --without-http_memcached_module --user=www --group=www --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-openssl --with-pcre

在升级前一定要提前备份好nginx程序和网站等文件,避免出错。