nginx升级与回退
前期说明
# 说明:
旧版本:nginx-1.16.1
新版本:nginx-1.18.0
# 安装方式
编译安装
# 操作全解释
这里主要为了nginx的升级操作,我之前博客也有一篇说明了nginx的编译升级,但需要拷贝文件较多,比较繁琐,但两篇文章都可参考。接下来也会对服务回滚进行演示。
# 旧博文参考地址
https://www.cnblogs.com/tcy1/p/12983811.html
旧版本nginx安装
# 1.下载安装包
[root@web01 ~]# wget http://nginx.org/download/nginx-1.16.1.tar.gz
# 2.解压
[root@web01 ~]# tar xf nginx-1.16.1.tar.gz
# 3.安装基础依赖
[root@web01 ~]# yum install -y openssl-devel pcre-devel zlib-devel
# 4.进入目录开始编译安装
[root@web01 ~]# cd nginx-1.16.1/
[root@web01 nginx-1.16.1]# ./configure --user=www --group=www --prefix=/application/nginx-1.16.0/ --with-http_stub_status_module --with-http_ssl_module --with-pcre
[root@web01 nginx-1.16.1]# make && make install
# 5.查看指定工作目录中的对应文件
[root@web01 nginx-1.16.1]# cd /application/
[root@web01 application]# cd nginx-1.16.0/
[root@web01 nginx-1.16.0]# ll
drwxr-xr-x 2 root root 333 Aug 31 19:31 conf
drwxr-xr-x 2 root root 40 Aug 31 19:31 html
drwxr-xr-x 2 root root 6 Aug 31 19:31 logs
drwxr-xr-x 2 root root 19 Aug 31 19:31 sbin
# 6.软连接
[root@web01 application]# ln -s nginx-1.16.0/ nginx
# 7.创建配置时指定的用户
[root@web01 application]# useradd www -s /sbin/nologin -M
# 8.指定work进程数
[root@web01 conf]# vim nginx.conf
worker_processes 5;
# 9.启动nginx,查看端口
[root@web01 sbin]# netstat -lntup
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 14656/nginx: master
# 10.修改html页面
[root@web01 conf]# vim /application/nginx/html/index.html
hello is me tcy
# 11.访问本地
[root@web01 html]# curl 127.0.0.1
curl 127.0.0.1
hello is me tcy
# 12.查看进程
[root@web01 sbin]# ps -ef|grep nginx
root 14809 1 0 19:41 ? 00:00:00 nginx: master process nginx
www 14810 14809 0 19:41 ? 00:00:00 nginx: worker process
www 14811 14809 0 19:41 ? 00:00:00 nginx: worker process
www 14812 14809 0 19:41 ? 00:00:00 nginx: worker process
www 14813 14809 0 19:41 ? 00:00:00 nginx: worker process
www 14814 14809 0 19:41 ? 00:00:00 nginx: worker process
root 14817 7497 0 19:41 pts/0 00:00:00 grep --color=auto nginx
新版本安装
# 1.下载新版本安装包
[root@web01 ~]# http://nginx.org/download/nginx-1.18.0.tar.gz
# 2.将安装解压
[root@web01 ~]# tar xf nginx-1.18.0.tar.gz -C /application/
# 3.查看旧版本的nginx编译选项
[root@web01 nginx-1.16.0]# cd sbin/
[root@web01 sbin]# ./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: --user=www --group=www --prefix=/application/nginx-1.16.0/ --with-http_stub_status_module --with-http_ssl_module --with-pcre
# 4.根据如上的编译参数,进入新的nginx目录中,进行生成,编译(注意,不要make install)
[root@web01 application]# cd nginx-1.18.0/
[root@web01 nginx-1.18.0]# ./configure --user=www --group=www --prefix=/application/nginx-1.16.0/ --with-http_stub_status_module --with-http_ssl_module --with-pcre
# 说明:
注意:有些人可能有疑惑,新下载的nginx在执行./configure的时候--prefix指定的目录是需要指向旧的nginx所指向的prefix目录还是随便指向一个就行,答案是需要指向旧版本的nginx的安装目录
# 5.对旧版本的nginx的二进制可执行程序进行备份
[root@web01 nginx-1.18.0]# cd /application/nginx/sbin/
[root@web01 sbin]# cp nginx{,.bak}
# 6.查看未升级前的nginx的版本
[root@web01 sbin]# ./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: --user=www --group=www --prefix=/application/nginx-1.16.0/ --with-http_stub_status_module --with-http_ssl_module --with-pcre
# 7.找到nginx新版本的nginx二进制程序
[root@web01 sbin]# cd /application/nginx-1.18.0/
[root@web01 nginx-1.18.0]# ls
auto CHANGES CHANGES.ru conf configure contrib html LICENSE Makefile man objs README src
[root@web01 nginx-1.18.0]# cd objs/
[root@web01 objs]# ll
total 5996
-rw-r--r-- 1 root root 17251 Aug 31 19:44 autoconf.err
-rw-r--r-- 1 root root 42017 Aug 31 19:44 Makefile
-rwxr-xr-x 1 root root 5952280 Aug 31 19:45 nginx # 就是这个nginx文件
-rw-r--r-- 1 root root 5415 Aug 31 19:45 nginx.8
-rw-r--r-- 1 root root 7271 Aug 31 19:44 ngx_auto_config.h
-rw-r--r-- 1 root root 657 Aug 31 19:44 ngx_auto_headers.h
-rw-r--r-- 1 root root 6162 Aug 31 19:44 ngx_modules.c
-rw-r--r-- 1 root root 87536 Aug 31 19:45 ngx_modules.o
drwxr-xr-x 9 root root 91 Aug 31 19:44 src
# 8.使用这里的新版本中的nginx可执行文件,对旧版本中的可执行文件强制替换
[root@web01 objs]# cp -f nginx /application/nginx/sbin/nginx
cp: overwrite ‘/application/nginx/sbin/nginx’? y
# 9.设定旧的服务不再接收用户请求(下线),新服务启动子进程接收用户请求(上线),查看nginx父进程pid
[root@web01 objs]# ps -aux|grep nginx
root 14809 0.0 0.2 45968 1128 ? Ss 19:41 0:00 nginx: master process nginx
www 14810 0.0 0.3 46424 1880 ? S 19:41 0:00 nginx: worker process
www 14811 0.0 0.3 46424 1880 ? S 19:41 0:00 nginx: worker process
www 14812 0.0 0.3 46424 1880 ? S 19:41 0:00 nginx: worker process
www 14813 0.0 0.3 46424 1880 ? S 19:41 0:00 nginx: worker process
www 14814 0.0 0.3 46424 1880 ? S 19:41 0:00 nginx: worker process
root 17472 0.0 0.2 112812 972 pts/0 R+ 19:47 0:00 grep --color=auto nginx
# 10.找到nginx父进程的pid号,现在对其发送USR2信号
[root@web01 objs]# kill -USR2 14809
# 11.再次查看进程
[root@web01 objs]# ps -aux|grep nginx
root 14809 0.0 0.2 45968 1228 ? Ss 19:41 0:00 nginx: master process nginx
www 14810 0.0 0.3 46424 1880 ? S 19:41 0:00 nginx: worker process
www 14811 0.0 0.3 46424 1880 ? S 19:41 0:00 nginx: worker process
www 14812 0.0 0.3 46424 1880 ? S 19:41 0:00 nginx: worker process
www 14813 0.0 0.3 46424 1880 ? S 19:41 0:00 nginx: worker process
www 14814 0.0 0.3 46424 1880 ? S 19:41 0:00 nginx: worker process
root 17479 0.0 0.6 45972 3300 ? S 19:52 0:00 nginx: master process nginx
www 17480 0.0 0.3 46416 1876 ? S 19:52 0:00 nginx: worker process
www 17481 0.0 0.3 46416 1876 ? S 19:52 0:00 nginx: worker process
www 17482 0.0 0.3 46416 1876 ? S 19:52 0:00 nginx: worker process
www 17483 0.0 0.3 46416 1876 ? S 19:52 0:00 nginx: worker process
www 17484 0.0 0.3 46416 1876 ? S 19:52 0:00 nginx: worker process
root 17486 0.0 0.2 112812 968 pts/0 R+ 19:52 0:00 grep --color=auto nginx
# 说明:
现在是nginx的新老版本的进程共存的一种情况。虽然现在旧版本的nginx进程还存在,但是已经不再接受用户的请求了。除此之外,旧版本的nginx进程也依然处于监听的状态,我们通过lsof命令可以看到,虽然在监听,但实际不会处理新连接,因为fd已经从epoll中移出了。另外,旧master是新master的父进程,所以新master才能共享打开的监听端口。保留旧版本的master是为了方便回滚(当然你可以发信号QUIT或者直接杀掉进程)
============================== 回退操作=========================================
# 彻底清理旧服务操作:
[root@web01 objs]# kill -WINCH 旧进程id # 进行旧服务进程的关闭,该pid号是旧版本的nginx的master进程的pid号
# 查看进程
[root@web01 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
nobody 21085 0.0 0.0 80192 2200 ? S 20:00 0:00 nginx: worker process
nobody 21086 0.0 0.0 80192 2200 ? S 20:00 0:00 nginx: worker process
# 说明
可以看到现在的旧版本的nginx的worker进程已经全部被杀死了,只剩下的旧版本nginx的master进程
确定升级没有任何问题的话,那么现在我们可以把这个master进程给杀死掉。可以用kill -QUIT把旧master进程杀掉。方法已经教给大家了,但是这里我先不杀死,因为我还要往下演示如何回退。
==================================================================================
# 查看当前版本(已经是升级成功)
[root@web01 sbin]# ./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.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --user=www --group=www --prefix=/application/nginx-1.16.0/ --with-http_stub_status_module --with-http_ssl_module --with-pcre
# 访问(就算升级完还是老样子,照常访问)
[root@web01 sbin]# curl 127.0.0.1
hello is me tcy
回退
说明
这种情况主要是用于当新版本的nginx升级失败之后,我们立马回退到旧版本的nginx
操作流程
# 1.将老版本的nginx的二进制备份文件强制覆盖
[root@web01 sbin]# mv nginx.bak nginx
# 2.查看进程
[root@web01 sbin]# ps aux|grep nginx
root 14809 0.0 0.2 45968 1228 ? Ss 19:41 0:00 nginx: master process nginx
www 14810 0.0 0.3 46424 1880 ? S 19:41 0:00 nginx: worker process
www 14811 0.0 0.3 46424 1880 ? S 19:41 0:00 nginx: worker process
www 14812 0.0 0.3 46424 1880 ? S 19:41 0:00 nginx: worker process
www 14813 0.0 0.3 46424 1880 ? S 19:41 0:00 nginx: worker process
www 14814 0.0 0.3 46424 1880 ? S 19:41 0:00 nginx: worker process
root 17479 0.0 0.6 45972 3300 ? S 19:52 0:00 nginx: master process nginx
www 17480 0.0 0.4 46416 2120 ? S 19:52 0:00 nginx: worker process
www 17481 0.0 0.3 46416 1876 ? S 19:52 0:00 nginx: worker process
www 17482 0.0 0.3 46416 1876 ? S 19:52 0:00 nginx: worker process
www 17483 0.0 0.3 46416 1876 ? S 19:52 0:00 nginx: worker process
www 17484 0.0 0.3 46416 1876 ? S 19:52 0:00 nginx: worker process
root 17544 0.0 0.2 112812 972 pts/0 R+ 20:03 0:00 grep --color=auto nginx
# 3.向旧版本nginx进程发送HUP信号
[root@web01 sbin]# kill -HUP 17479 #注意这是旧版本的nginx进程pid号
# 说明:
说明一下:这个命令就相当与reload指令的作用,把旧的nginx的worker进程拉起来,但是咱们并不是直接使用reload的方式来执行,而是发送HUP信号,它会在没有worker进程时启动worker进程,这点需要注意一下。此时再次查看进程
# 4.让新版本的服务停止接收用户请求,此时,接收用户请求的是旧版本的nginx进程。新版本的nginx进程不再接受用户请求
[root@web01 sbin]# kill -USR2 14809
# 5.彻底关闭新版本进程
[root@web01 sbin]# kill -WINCH 14809
# 6.查看进程
[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
nobody 42073 0.0 0.0 80120 2208 ? S 15:42 0:00 nginx: worker process
nobody 42074 0.0 0.0 80120 2208 ? S 15:42 0:00 nginx: worker process
# 7.现在,旧版本已经回退成功了,我们可以把新版本的nginx的master进程发送QUIT进程将其退出,kill掉新版本nginx进程。
[root@web01 sbin]# kill -QUIT 14809
# 8.再次查看进程
[root@web01 sbin]# ps aux |grep nginx
root 17479 0.0 0.7 46108 3432 ? S 19:52 0:00 nginx: master process nginx
www 17545 0.0 0.4 46536 1996 ? S 20:04 0:00 nginx: worker process
www 17546 0.0 0.4 46536 1996 ? S 20:04 0:00 nginx: worker process
www 17547 0.0 0.4 46536 1996 ? S 20:04 0:00 nginx: worker process
www 17548 0.0 0.4 46536 1996 ? S 20:04 0:00 nginx: worker process
www 17549 0.0 0.4 46536 1996 ? S 20:04 0:00 nginx: worker process
root 17567 0.0 0.2 112816 968 pts/0 S+ 20:06 0:00 grep --color=auto nginx
总结
kill -USR2 # 让新版本的服务停止接收用户请求,此时,接收用户请求的是旧版本的nginx进程。新版本的nginx进程不再接受用户请求
kill -WINCH # 的关闭,该pid号是旧版本的nginx的master进程的pid号
kill -QUIT # 让进程退出,结果是进程退出
kill -HUP # 如nginx配置文件有修改,但不想重启服务,可重新加载