# Linux下Nginx1.16.1升级至1.18.0 {#linux下nginx1-16-1升级至1-18-0}
前置条件
本文采用centOS 7.8.2003 版本
通过编译的方式升级
如何平滑的升级Nginx 1.16.1到1.18.0版本,及升级失败后如何退回
# 一、首先确认当前已经安装Nginx {#一、首先确认当前已经安装nginx}
ps -ef|grep nginx
# 二、下载Nginx 1.18.0 {#二、下载nginx-1-18-0}
# 下载
wget http://nginx.org/download/nginx-1.18.0.tar.gz
# 移动至目标文件夹
mv nginx-1.18.0.tar.gz /usr/local/src/
cd /usr/local/src/
# 解压
tar -zxvf nginx-1.18.0.tar.gz
cd nginx-1.18.0
# 三、获取旧版本的安装编译命令 {#三、获取旧版本的安装编译命令}
注意
下面命令中 /usr/local/nginx/sbin/nginx
是我的nginx安装路径
若路径不一致可根据实际情况进行修改
/usr/local/nginx/sbin/nginx -V
-
此处我们得到了编译参数为
--prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-stream
注意
编译参数可能有出入,此处请根据实际情况替换成你自己获取的参数
# 四、编译 {#四、编译}
-
此处
./configure
后面的命令为上面获取的编译参数,若想了解此文章的参数具体含义可以点击此处./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-stream
注意
有些人可能有疑惑,新下载的nginx在执行./configure的时候--prefix指定的目录是需要指向旧的nginx所指向的prefix目录还是随便指向一个就行,答案是需要指向旧版本的nginx的安装目录
-
执行make命令
make
注意
注意执行完成后不要执行make install命令
# 五、平滑升级 {#五、平滑升级}
# 1. 首先备份nginx二进制可执行程序 {#_1-首先备份nginx二进制可执行程序}
cd /usr/local/nginx/sbin/
cp nginx{,.bak}
# 2. 查看nginx版本 {#_2-查看nginx版本}
./nginx -V
# 3. 找到nginx-1.18.0新版本的nginx的二进制执行程序 {#_3-找到nginx-1-18-0新版本的nginx的二进制执行程序}
cd /usr/local/src/nginx-1.18.0/objs
上面的这个nginx
就是我们要拿到的新版本的nginx可执行程序文件。
# 4. 使用nginx-1.18.0的二进制文件将nginx-1.16.1的二进制文件进行强制覆盖 {#_4-使用nginx-1-18-0的二进制文件将nginx-1-16-1的二进制文件进行强制覆盖}
cp -f nginx /usr/local/nginx/sbin/nginx
# 5. 设定旧的服务不再接收用户请求(下线),新服务启动子进程接收用户请求(上线) {#_5-设定旧的服务不再接收用户请求-下线-,新服务启动子进程接收用户请求-上线}
ps aux | grep nginx
-
找到nginx父进程的pid号,现在对其发送
USR2
信号kill -USR2 6084 #设定新的子进程开始接收用户的访问请求,旧的不再接受用户的访问请求
-
再次查看进程
ps aux | grep nginx
现在是nginx的新老版本的进程共存的一种情况。虽然现在旧版本的nginx进程还存在,但是已经不再接受用户的请求了。除此之外,旧版本的nginx进程也依然处于监听的状态,我们通过lsof命令可以看到,此处端口号为父进程端口号
虽然在监听,但实际不会处理新连接,因为fd已经从epoll中移出了。另外,旧master是新master的父进程,所以新master才能共享打开的监听端口。保留旧版本的master是为了方便回滚(当然你可以发信号QUIT或者直接杀掉进程)
# 6. 进行旧服务进程的关闭 {#_6-进行旧服务进程的关闭}
kill -WINCH 6084 # 进行旧服务进程的关闭,该pid号是旧版本的nginx的master进程的pid号
-
再次查看当前nginx进程
ps aux | grep nginx
可以看到现在的旧版本的nginx的worker进程已经全部被杀死了,只剩下的旧版本nginx的master进程 确定升级没有任何问题的话,那么现在我们可以把这个master进程给杀死掉。可以用kill -QUIT把旧master进程杀掉。方法已经教给大家了,但是这里我先不杀死,因为我还要往下演示如何回退。
# 7. 查看当前nginx的版本 {#_7-查看当前nginx的版本}
/usr/local/nginx/sbin/nginx -V
可以看到现在已经升级成功了。 还可以访问一下
# 六、如何退回到1.16.1版本 {#六、如何退回到1-16-1版本}
这种情况主要是用于当新版本的nginx升级失败之后,我们立马回退到旧版本的nginx
# 1. 将旧版本的nginx二进制文件强行覆盖 {#_1-将旧版本的nginx二进制文件强行覆盖}
cd /usr/local/nginx/sbin/
mv nginx.bak nginx
-
查看进程
ps aux | grep nginx
# 2. 向旧版本nginx进程发送HUP信号 {#_2-向旧版本nginx进程发送hup信号}
kill -HUP 6084 #注意这是旧版本的nginx进程pid号
说明
这个命令就相当与reload指令的作用,把旧的nginx的worker进程拉起来,但是咱们并不是直接使用reload的方式来执行,而是发送HUP信号,它会在没有worker进程时启动worker进程,这点需要注意一下。
-
此时再次查看进程
ps aux | grep nginx
发现多了worker进程,多出来的部分是旧版本的nginx进程。
# 3. 让新版本的服务停止接收用户请求 {#_3-让新版本的服务停止接收用户请求}
kill -USR2 31276
此时,接收用户请求的是旧版本的nginx进程。新版本的nginx进程不再接受用户请求
# 4. 进行新版本服务进程的关闭 {#_4-进行新版本服务进程的关闭}
kill -WINCH 31276
-
查看一下进程
ps aux | grep nginx
现在,旧版本已经回退成功了,我们可以把新版本的nginx的master进程发送QUIT进程将其退出。
# 5. kill掉新版本nginx进程 {#_5-kill掉新版本nginx进程}
kill -QUIT 31276
ps aux | grep nginx
-
再次查看一下版本
./nginx -V
退回成功