nginx升级与回退
一、查看旧版本nginx,启动了3个worker进程
[root@master2 objs]# ps aux | grep nginx root 17440 0.0 0.0 79732 1496 ? Ss 11:42 0:00 nginx: master process sbin/nginx nobody 17441 0.0 0.0 80120 2212 ? S 11:42 0:00 nginx: worker process nobody 17442 0.0 0.1 80120 2456 ? S 11:42 0:00 nginx: worker process nobody 17443 0.0 0.0 80120 2212 ? S 11:42 0:00 nginx: worker process
二、 编译安装新版本nginx
1、下载源码包
wget http://nginx.org/download/nginx-1.18.0.tar.gz mv nginx-1.18.0.tar.gz /usr/local cd /usr/local tar xf nginx-1.18.0.tar.gz
2、获取旧版本的编译参数
[root@master2 nginx]# nginx -V nginx version: nginx/1.16.1 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC) built with OpenSSL 1.0.2k-fips 26 Jan 2017 TLS SNI support enabled configure arguments: --prefix=/app/nginx --conf-path=/app/nginx/conf/nginx.conf --sbin-path=/app/nginx/sbin/nginx --http-log-path=/app/nginx/logs/access.log --error-log-path=/app/nginx/logs/error.log --pid-path=/app/nginx/logs/nginx.pid --lock-path=/app/nginx/logs/nginx.lock --with-ld-opt=-Wl,-rpath,/usr/local/lib --with-pcre=/usr/local/src/pcre-8.42 --with-zlib=/usr/local/src/zlib-1.2.11 --with-openssl=/usr/local/src/openssl-1.0.2n --add-module=/usr/local/src/nginx_upstream_check_module-0.3.0 --add-module=/usr/local/src/nginx-sticky-module-1.1/ --add-module=/usr/local/src/nginx-upstream-fair-master --add-module=/usr/local/src/ngx_cache_purge-2.3 --add-module=/usr/local/src/lua-nginx-module-0.10.13 --add-module=/usr/local/src/ngx_devel_kit-0.3.0 --add-module=/usr/local/src/set-misc-nginx-module-0.32 --with-http_addition_module --with-http_dav_module --with-http_flv_module --with-http_gzip_static_module --with-http_realip_module --with-http_stub_status_module --with-http_ssl_module --with-stream_ssl_preread_module --with-stream --user=nginx --group=nginx
3、在新版本nginx中利用这些选项进行编译,新nginx在执行./configure的时候--prefix指定的目录是需要指向旧的nginx所指向的prefix目录。
cd /usr/local/nginx-1.18.0 ./configure --prefix=/app/nginx --conf-path=/app/nginx/conf/nginx.conf --sbin-path=/app/nginx/sbin/nginx --http-log-path=/app/nginx/logs/access.log --error-log-path=/app/nginx/logs/error.log --pid-path=/app/nginx/logs/nginx.pid --lock-path=/app/nginx/logs/nginx.lock --with-ld-opt=-Wl,-rpath,/usr/local/lib --with-pcre=/usr/local/src/pcre-8.42 --with-zlib=/usr/local/src/zlib-1.2.11 --with-openssl=/usr/local/src/openssl-1.0.2n --add-module=/usr/local/src/nginx_upstream_check_module-0.3.0 --add-module=/usr/local/src/nginx-sticky-module-1.1/ --add-module=/usr/local/src/nginx-upstream-fair-master --add-module=/usr/local/src/ngx_cache_purge-2.3 --add-module=/usr/local/src/lua-nginx-module-0.10.13 --add-module=/usr/local/src/ngx_devel_kit-0.3.0 --add-module=/usr/local/src/set-misc-nginx-module-0.32 --with-http_addition_module --with-http_dav_module --with-http_flv_module --with-http_gzip_static_module --with-http_realip_module --with-http_stub_status_module --with-http_ssl_module --with-stream_ssl_preread_module --with-stream --user=nginx --group=nginx make
执行make完成之后不要执行make install指令
三、平滑升级
1、备份旧的nginx可执行文件
cd /usr/local/nginx/sbin cp nginx{,.bak}
2、找到新nginx的二进制执行文件
[root@master2 objs]# cd /usr/local/nginx-1.18.0/objs/ [root@master2 objs]# ls autoconf.err Makefile nginx nginx.8 ngx_auto_config.h ngx_auto_headers.h ngx_modules.c ngx_modules.o src
3、使用新nginx的二进制文件将旧nginx的二进制文件进行强制覆盖
cp -f nginx /usr/local/nginx/sbin/nginx
4、旧的服务不再接收用户请求(下线),新服务启动子进程接收用户请求(上线)
先查看当前未升级的nginx进程(这是旧版本的nginx进程)
[root@master2 objs]# ps aux | grep nginx root 17440 0.0 0.0 79732 1496 ? Ss 11:42 0:00 nginx: master process sbin/nginx nobody 17441 0.0 0.0 80120 2212 ? S 11:42 0:00 nginx: worker process nobody 17442 0.0 0.1 80120 2456 ? S 11:42 0:00 nginx: worker process nobody 17443 0.0 0.0 80120 2212 ? S 11:42 0:00 nginx: worker process
找到nginx父进程的pid号,现在对其发送USR2信号
kill -USR2 17440
再次查看进程
[root@master2 objs]# ps aux | grep nginx root 17440 0.0 0.0 79732 1496 ? Ss 11:42 0:00 nginx: master process sbin/nginx nobody 17441 0.0 0.0 80120 2212 ? S 11:42 0:00 nginx: worker process nobody 17442 0.0 0.1 80120 2456 ? S 11:42 0:00 nginx: worker process nobody 17443 0.0 0.0 80120 2212 ? S 11:42 0:00 nginx: worker process root 21081 0.5 0.1 79740 4080 ? S 20:00 0:00 nginx: master process sbin/nginx nobody 21082 0.0 0.0 80192 2200 ? S 20:00 0:00 nginx: worker process nobody 21083 0.0 0.0 80192 2200 ? S 20:00 0:00 nginx: worker process nobody 21084 0.0 0.0 80192 2200 ? S 20:00 0:00 nginx: worker process
现在是nginx的新老版本的进程共存的一种情况。虽然现在旧版本的nginx进程还存在,但是已经不再接受用户的请求了。除此之外,旧版本的nginx进程也依然处于监听的状态,虽然在监听,但实际不会处理新连接,因为fd已经从epoll中移出了。另外,旧master是新master的父进程,所以新master才能共享打开的监听端口。保留旧版本的master是为了方便回滚(当然你可以发信号QUIT或者直接杀掉进程)。
5、关闭旧服务进程
kill -WINCH 17440
再次查看当前nginx进程
[root@master2 objs]# ps aux | grep nginx root 17440 0.0 0.0 79732 1652 ? Ss 11:42 0:00 nginx: master process sbin/nginx root 21081 0.0 0.1 79740 4080 ? S 20:00 0:00 nginx: master process sbin/nginx nobody 21082 0.0 0.0 80192 2200 ? S 20:00 0:00 nginx: worker process nobody 21083 0.0 0.0 80192 2200 ? S 20:00 0:00 nginx: worker process nobody 21084 0.0 0.0 80192 2200 ? S 20:00 0:00 nginx: worker process
旧版本的nginx的worker进程已经全部被杀死了,只剩下的旧版本nginx的master进程
此时进行业务验证,如果有问题在此处立即回退,如果没有任何问题,就可以把旧版本的master进程给杀掉。
kill -QUIT 17440
查看当前nginx版本
[root@master2 ~]# nginx -V nginx version: nginx/1.18.0 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC) built with OpenSSL 1.0.2n 7 Dec 2017 TLS SNI support enabled configure arguments: --prefix=/app/nginx --conf-path=/app/nginx/conf/nginx.conf --sbin-path=/app/nginx/sbin/nginx --http-log-path=/app/nginx/logs/access.log --error-log-path=/app/nginx/logs/error.log --pid-path=/app/nginx/logs/nginx.pid --lock-path=/app/nginx/logs/nginx.lock --with-ld-opt=-Wl,-rpath,/usr/local/lib --with-pcre=/usr/local/src/pcre-8.42 --with-zlib=/usr/local/src/zlib-1.2.11 --with-openssl=/usr/local/src/openssl-1.0.2n --add-module=/usr/local/src/nginx_upstream_check_module-0.3.0 --add-module=/usr/local/src/nginx-sticky-module-1.1/ --add-module=/usr/local/src/nginx-upstream-fair-master --add-module=/usr/local/src/ngx_cache_purge-2.3 --add-module=/usr/local/src/lua-nginx-module-0.10.13 --add-module=/usr/local/src/ngx_devel_kit-0.3.0 --add-module=/usr/local/src/set-misc-nginx-module-0.32 --with-http_addition_module --with-http_dav_module --with-http_flv_module --with-http_gzip_static_module --with-http_realip_module --with-http_stub_status_module --with-http_ssl_module --with-stream_ssl_preread_module --with-stream --user=nginx --group=nginx
升级成功。
四、回退
1、将旧版本的nginx二进制文件强行覆盖
mv nginx.bak nginx
查看进程
[root@master2 objs]# ps aux | grep nginx root 17440 0.0 0.0 79732 1652 ? Ss 11:42 0:00 nginx: master process sbin/nginx root 21081 0.0 0.1 79740 4080 ? S 20:00 0:00 nginx: master process sbin/nginx nobody 21082 0.0 0.0 80192 2200 ? S 20:00 0:00 nginx: worker process nobody 21083 0.0 0.0 80192 2200 ? S 20:00 0:00 nginx: worker process nobody 21084 0.0 0.0 80192 2200 ? S 20:00 0:00 nginx: worker process
2、向旧版本nginx进程发送HUP信号
kill -HUP 17440
这个命令就相当与reload指令的作用,把旧的nginx的worker进程拉起来,但是并不是直接使用reload的方式来执行,而是发送HUP信号,它会在没有worker进程时启动worker进程。
[root@master2 sbin]# ps aux | grep nginx root 17440 0.0 0.0 79732 1652 ? Ss Aug20 0:00 nginx: master process sbin/nginx root 21081 0.0 0.1 79740 4080 ? S Aug20 0:00 nginx: master process sbin/nginx nobody 21082 0.0 0.0 80192 2200 ? S Aug20 0:00 nginx: worker process nobody 21083 0.0 0.1 80192 2452 ? S Aug20 0:00 nginx: worker process nobody 21084 0.0 0.0 80192 2200 ? S Aug20 0:00 nginx: worker process nobody 42070 0.0 0.0 80120 2208 ? S 15:42 0:00 nginx: worker process nobody 42071 0.0 0.0 80120 2208 ? S 15:42 0:00 nginx: worker process nobody 42072 0.0 0.0 80120 2208 ? S 15:42 0:00 nginx: worker process
3、让新版本的服务停止接收用户请求
kill -USR2 21081
此时,接收用户请求的是旧版本的nginx进程。新版本的nginx进程不再接受用户请求
4、进行新版本服务进程的关闭
kill -WINCH 21081
查看一下进程
[root@master2 sbin]# ps aux | grep nginx root 17440 0.0 0.0 79732 1652 ? Ss Aug20 0:00 nginx: master process sbin/nginx root 21081 0.0 0.1 79740 4080 ? S Aug20 0:00 nginx: master process sbin/nginx nobody 42070 0.0 0.0 80120 2208 ? S 15:42 0:00 nginx: worker process nobody 42071 0.0 0.0 80120 2208 ? S 15:42 0:00 nginx: worker process nobody 42072 0.0 0.0 80120 2208 ? S 15:42 0:00 nginx: worker process
现在,旧版本已经回退成功了,我们可以把新版本的nginx的master进程发送QUIT进程将其退出。
5、kill掉新版本nginx进程
[root@master2 sbin]# kill -QUIT 21081 [root@master2 sbin]# ps aux | grep nginx root 17440 0.0 0.0 79732 1652 ? Ss Aug20 0:00 nginx: master process sbin/nginx nobody 42070 0.0 0.0 80120 2208 ? S 15:42 0:00 nginx: worker process nobody 42071 0.0 0.0 80120 2208 ? S 15:42 0:00 nginx: worker process nobody 42072 0.0 0.0 80120 2208 ? S 15:42 0:00 nginx: worker process