经典案例-Nginx 平滑升级回滚实战
#首先我们编译安装低版本:1.18版本
#首先我们编译安装低版本:1.18版本:
[20:00:34 root@rocky8 ~]#bash install_nginx_v0.sh
...
est -d '/apps/nginx/logs' \
|| mkdir -p '/apps/nginx/logs'
test -d '/apps/nginx/logs' \
|| mkdir -p '/apps/nginx/logs'
test -d '/apps/nginx/html' \
|| cp -R html '/apps/nginx'
test -d '/apps/nginx/logs' \
|| mkdir -p '/apps/nginx/logs'
make[1]: 离开目录“/usr/local/src/nginx-1.18.0”
nginx 编译安装成功 [ OK ]
nginx 安装完成 [ OK ]
[20:00:23 root@rocky8 ~]#
查看一下当前版本:[20:00:34 root@rocky8 ~]#nginx -v
nginx version: nginx/1.18.0
查看一下编译安装时的选项:
[20:03:12 root@rocky8 ~]#nginx -V
nginx version: nginx/1.18.0
built by gcc 8.5.0 20210514 (Red Hat 8.5.0-4) (GCC)
built with OpenSSL 1.1.1k FIPS 25 Mar 2021
TLS SNI support enabled
configure arguments: --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module
#configure arguments后面是以前编译时的参数。现在编译使用一样的参数
#
[21:54:02 root@rocky8 logs]#cp nginx.pid nginx.pid.oldbin #对nginx.pid进行改名拷贝一份
[21:54:19 root@rocky8 logs]#ls
access.log error.log nginx.pid nginx.pid.oldbin
@以上操作做完直接跳到下面#下载最新稳定版本那一步,以下写的特别注意可以顺带看一下!
#特别注意1:
---------------------------------------------------------------------------------------------------
[22:06:18 root@rocky8 nginx-1.20.1]#cat /apps/nginx/logs/nginx.pid.oldbin
10802
[22:07:16 root@rocky8 nginx-1.20.1]#ps auxf | grep nginx
root 13862 0.0 0.0 12348 1032 pts/0 S+ 22:08 0:00 \_ grep --color=auto nginx
root 10802 0.0 0.0 42460 840 ? Ss 21:53 0:00 nginx: master process /apps/nginx/sbin/nginx
nginx 10803 0.0 0.2 77128 4728 ? S 21:53 0:00 \_ nginx: worker process
---------------------------------------------------------------------------------------------
#主进程的PID号就是当时备份的那个PID进程号(也就是说nginx.pid和nginx.pid.oldbin的pid号目前暂时是一样的,这个后面需要用到,回滚时,主进程(master进程)是不能关闭的。不然没有主进程PID号在无法实现回滚操作)
#特别注意2:
---------------------------------------------------------------------------------------------
[22:14:21 root@rocky8 nginx-1.20.1]#ps auxf | grep nginx
root 13879 0.0 0.0 12348 1152 pts/0 S+ 22:14 0:00 \_ grep --color=auto nginx
root 10802 0.0 0.1 42460 2716 ? Ss 21:53 0:00 nginx: master process /apps/nginx/sbin/nginx
nginx 10803 0.0 0.2 77128 4728 ? S 21:53 0:00 \_ nginx: worker process
root 13875 0.0 0.3 42488 6036 ? S 22:14 0:00 \_ nginx: master process /apps/nginx/sbin/nginx
nginx 13876 0.0 0.2 77244 4848 ? S 22:14 0:00 \_ nginx: worker process
[22:14:38 root@rocky8 nginx-1.20.1]#kill -WINCH `cat /apps/nginx/logs/nginx.pid.oldbin`
[22:15:45 root@rocky8 nginx-1.20.1]#ps auxf | grep nginx
root 13882 0.0 0.0 12348 1172 pts/0 S+ 22:16 0:00 \_ grep --color=auto nginx
root 10802 0.0 0.1 42460 2716 ? Ss 21:53 0:00 nginx: master process /apps/nginx/sbin/nginx
root 13875 0.0 0.3 42488 6036 ? S 22:14 0:00 \_ nginx: master process /apps/nginx/sbin/nginx
nginx 13876 0.0 0.2 77244 4848 ? S 22:14 0:00 \_ nginx: worker process
---------------------------------------------------------------------------------------------
#这边可以对比前后升级过程版本,进程开启和关闭的状态。此时是原master主进程没有关闭,原先的worker进程已经关闭。
@
#首先下载最新稳定版
[19:46:20 root@rocky8 ~]#wget http://nginx.org/download/nginx-1.20.1.tar.gz
--2022-06-09 19:46:39-- http://nginx.org/download/nginx-1.20.1.tar.gz
正在解析主机 nginx.org (nginx.org)... 3.125.197.172, 52.58.199.22, 2a05:d014:edb:5702::6, ...
正在连接 nginx.org (nginx.org)|3.125.197.172|:80... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:1061461 (1.0M) [application/octet-stream]
正在保存至: “nginx-1.20.1.tar.gz”
nginx-1.20.1.tar.gz 100%[====================================================>] 1.01M 262KB/s 用时 3.9s
2022-06-09 19:46:44 (262 KB/s) - 已保存 “nginx-1.20.1.tar.gz” [1061461/1061461])
[19:46:44 root@rocky8 ~]#ls
anaconda-ks.cfg hjd init_for_centos_or_ubuntu-Mirrors-Update.sh linux.txt nginx-1.20.1.tar.gz win.txt
[19:46:46 root@rocky8 ~]#tar xvf nginx-1.20.1.tar.gz
nginx-1.20.1/
nginx-1.20.1/auto/
nginx-1.20.1/conf/
...
[20:07:36 root@rocky8 ~]#ls
anaconda-ks.cfg init_for_centos_or_ubuntu-Mirrors-Update.sh linux.txt nginx-1.20.1.tar.gz
hjd install_nginx_v0.sh nginx-1.20.1 win.txt
#可以看出已经解压出来了。
#开始编译新版本
#开始编译新版本:
[20:07:37 root@rocky8 ~]#cd nginx-1.20.1/
[20:09:00 root@rocky8 nginx-1.20.1]#
#查看当前使用的版本及编译选项。结果如下:
[20:09:00 root@rocky8 nginx-1.20.1]#/apps/nginx/sbin/nginx -V
nginx version: nginx/1.18.0
built by gcc 8.5.0 20210514 (Red Hat 8.5.0-4) (GCC)
built with OpenSSL 1.1.1k FIPS 25 Mar 2021
TLS SNI support enabled
configure arguments: --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module
#configure arguments后面是以前编译时的参数。现在编译使用一样的参数
[20:10:17 root@rocky8 nginx-1.20.1]#./configure --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module
#只要make无需要make install:
[20:11:22 root@rocky8 nginx-1.20.1]#make
make -f objs/Makefile
make[1]: 进入目录“/root/nginx-1.20.1”
cc -c -pipe -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs \
-o objs/src/core/nginx.o \
src/core/nginx.c
cc -c -pipe -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs \
-o objs/src/core/ngx_log.o \
...
sed -e "s|%%PREFIX%%|/apps/nginx|" \
-e "s|%%PID_PATH%%|/apps/nginx/logs/nginx.pid|" \
-e "s|%%CONF_PATH%%|/apps/nginx/conf/nginx.conf|" \
-e "s|%%ERROR_LOG_PATH%%|/apps/nginx/logs/error.log|" \
< man/nginx.8 > objs/nginx.8
make[1]: 离开目录“/root/nginx-1.20.1”
[20:12:51 root@rocky8 nginx-1.20.1]#
#查看新版本情况
[20:14:06 root@rocky8 nginx-1.20.1]#objs/nginx -V
nginx version: nginx/1.20.1
built by gcc 8.5.0 20210514 (Red Hat 8.5.0-4) (GCC)
built with OpenSSL 1.1.1k FIPS 25 Mar 2021
TLS SNI support enabled
configure arguments: --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module
[20:14:11 root@rocky8 nginx-1.20.1]#objs/nginx -v
nginx version: nginx/1.20.1
查看一下两个版本
[20:14:15 root@rocky8 nginx-1.20.1]#ll objs/nginx /apps/nginx/sbin/nginx
-rwxr-xr-x 1 root root 7596408 6月 9 20:00 /apps/nginx/sbin/nginx
-rwxr-xr-x 1 root root 7728552 6月 9 20:12 objs/nginx
#这时我们需要将旧版本的NGINX命令进行备份:
[20:22:48 root@rocky8 nginx-1.20.1]#cp /apps/nginx/sbin/nginx /opt/nginx.old
#把新版本的nginx命令复制过去覆盖旧版本程序文件,注意:需要加 -f 选项强制覆盖,否则会提示Text
file busy
[20:24:51 root@rocky8 nginx-1.20.1]#cp objs/nginx /apps/nginx/sbin/
cp:是否覆盖'/apps/nginx/sbin/nginx'? y
cp: 无法创建普通文件'/apps/nginx/sbin/nginx': 文本文件忙
#这个原因是需要加 -f 进行强制覆盖:
#[20:28:44 root@rocky8 nginx-1.20.1]#cp -f ./objs/nginx /apps/nginx/sbin/
cp:是否覆盖'/apps/nginx/sbin/nginx'? y
#此时检测一下有没有问题:
[20:29:39 root@rocky8 nginx-1.20.1]#/apps/nginx/sbin/nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
#经检测是OK的
附知识扩展:
知识扩展
附知识扩展:
#发送信号USR2 平滑升级可执行程序,将存储有旧版本主进程PID的文件重命名为nginx.pid.oldbin,并
启动新的nginx
#此时两个master的进程都在运行,只是旧的master不在监听,由新的master监听80
#此时Nginx开启一个新的master进程,这个master进程会生成新的worker进程,这就是升级后的Nginx
进程,此时老的进程不会自动退出,但是当接收到新的请求不作处理而是交给新的进程处理。
[21:37:39 root@rocky8 nginx-1.20.1]#cat /apps/nginx/logs/nginx.pid
10835
[20:33:54 root@rocky8 nginx-1.20.1]#kill -USR2 `cat /apps/nginx/logs/nginx.pid`
#可以看到两个master,新的master是旧版master的子进程,并生成新版的worker进程
[20:36:05 root@rocky8 nginx-1.20.1]#ps auxf|grep nginx
root 13952 0.0 0.0 12348 1036 pts/0 S+ 20:37 0:00 \_ grep --color=auto nginx
root 10827 0.0 0.1 42460 2680 ? Ss 20:00 0:00 nginx: master process /apps/nginx/sbin/nginx
nginx 10828 0.0 0.2 77128 4768 ? S 20:00 0:00 \_ nginx: worker process
root 13949 0.0 0.2 42488 5892 ? S 20:36 0:00 \_ nginx: master process /apps/nginx/sbin/nginx
nginx 13950 0.0 0.2 77244 5092 ? S 20:36 0:00 \_ nginx: worker process
[20:37:06 root@rocky8 nginx-1.20.1]#

#接下来查看80端口的占用情况
[20:37:06 root@rocky8 nginx-1.20.1]#lsof -i :80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nginx 10827 root 8u IPv4 45029 0t0 TCP *:http (LISTEN)
nginx 10828 nginx 8u IPv4 45029 0t0 TCP *:http (LISTEN)
nginx 13949 root 8u IPv4 45029 0t0 TCP *:http (LISTEN)
nginx 13950 nginx 8u IPv4 45029 0t0 TCP *:http (LISTEN)
#先关闭旧nginx的worker进程,而不关闭nginx主进程方便回滚
#向原Nginx主进程发送WINCH信号,它会逐步关闭旗下的工作进程(主进程不退出),这时所有请求都会由
新版Nginx处理
[20:45:08 root@rocky8 nginx-1.20.1]#kill -WINCH `cat /apps/nginx/logs/nginx.pid.oldbin`
#如果旧版worker进程有用户的请求,会一直等待处理完后才会关闭
此时再查看一下进程情况:
[20:46:07 root@rocky8 nginx-1.20.1]#ps auxf | grep nginx
root 13976 0.0 0.0 12348 1144 pts/0 S+ 20:48 0:00 \_ grep --color=auto nginx
root 10827 0.0 0.1 42460 2680 ? Ss 20:00 0:00 nginx: master process /apps/nginx/sbin/nginx
root 13949 0.0 0.2 42488 5892 ? S 20:36 0:00 \_ nginx: master process /apps/nginx/sbin/nginx
nginx 13950 0.0 0.2 77244 5092 ? S 20:36 0:00 \_ nginx: worker process
#此时我们这边可以看到旧版本nginx的worker进程已经关闭。主进程没有关闭
#这边我们可以pstree看一下
[20:52:01 root@rocky8 nginx-1.20.1]#pstree -p | grep nginx
|-nginx(10827)---nginx(13949)---nginx(13950)
#经过一段时间测试,新版本服务没问题,最后发送QUIT信号,退出老的master,这部要慎重,确定新版本稳定再执行操作!测试回滚状态这边可以跳过!目前已经是最新版本了 只不过老master的主进程一直是存在的,与新master主进程共存。可以做回滚操作!
[20:53:33 root@rocky8 nginx-1.20.1]#kill -QUIT `cat /apps/nginx/logs/nginx.pid.oldbin`
#查看版本是不是已经是新版了
[20:54:12 root@rocky8 nginx-1.20.1]#nginx -v
nginx version: nginx/1.20.1
[20:56:51 root@rocky8 nginx-1.20.1]#curl -I 127.0.0.1
HTTP/1.1 200 OK
Server: nginx/1.20.1
Date: Thu, 09 Jun 2022 12:57:23 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Thu, 09 Jun 2022 12:00:22 GMT
Connection: keep-alive
ETag: "62a1e0d6-264"
Accept-Ranges: bytes
可以看到已经平滑升级到1.20.1版本
#接下来就是回滚了
#回滚:
#如果升级的版本发现问题需要回滚,可以发送HUP信号,重新拉起旧版本的worker
[22:27:17 root@rocky8 nginx-1.20.1]#kill -HUP `cat /apps/nginx/logs/nginx.pid.oldbin`
[22:23:23 root@rocky8 nginx-1.20.1]#pstree -p | grep nginx
|-nginx(10802)---nginx(13875)---nginx(13876)
[22:27:17 root@rocky8 nginx-1.20.1]#kill -HUP `cat /apps/nginx/logs/nginx.pid.oldbin`
[22:27:52 root@rocky8 nginx-1.20.1]#pstree -p | grep nginx
|-nginx(10802)-+-nginx(13875)---nginx(13876)
| `-nginx(13893)
[22:28:14 root@rocky8 nginx-1.20.1]#ps auxf | grep nginx
root 13897 0.0 0.0 12348 1108 pts/0 S+ 22:28 0:00 \_ grep --color=auto nginx
root 10802 0.0 0.1 42460 2716 ? Ss 21:53 0:00 nginx: master process /apps/nginx/sbin/nginx
root 13875 0.0 0.3 42488 6036 ? S 22:14 0:00 \_ nginx: master process /apps/nginx/sbin/nginx
nginx 13876 0.0 0.2 77244 5232 ? S 22:14 0:00 | \_ nginx: worker process
nginx 13893 0.0 0.2 77128 4724 ? S 22:27 0:00 \_ nginx: worker process
这边可以看到PID进程号worker进程已经起来了。
#最后关闭新版的master:
[22:28:36 root@rocky8 nginx-1.20.1]#nginx -v
nginx version: nginx/1.20.1
[22:33:35 root@rocky8 nginx-1.20.1]#kill -QUIT `cat /apps/nginx/logs/nginx.pid`
[22:33:49 root@rocky8 nginx-1.20.1]#ps auxf | grep nginx
root 13903 0.0 0.0 12348 1092 pts/0 S+ 22:33 0:00 \_ grep --color=auto nginx
root 10802 0.0 0.1 42460 2716 ? Ss 21:53 0:00 nginx: master process /apps/nginx/sbin/nginx
nginx 13893 0.0 0.2 77128 4724 ? S 22:27 0:00 \_ nginx: worker process
#恢复旧版的文件:
[22:34:33 root@rocky8 nginx-1.20.1]#mv /opt/nginx.old /apps/nginx/sbin/ #把老版本的nginx启动文件移到/apps/nginx/sbin 里面。
[22:36:00 root@rocky8 nginx-1.20.1]#cd /apps/nginx/sbin/
[22:36:15 root@rocky8 sbin]#ls
nginx nginx.old
#把新版本的nginx程序启动文件移走
[22:37:19 root@rocky8 sbin]#mv /apps/nginx/sbin/nginx /opt/
[22:37:27 root@rocky8 sbin]#ls
nginx.old
#这边要进行改名,不然启动或者加载(平滑reload)不了,启动路径为/usr/sbin/nginx 或者直接覆盖也行!我这边是移走了改名!
#报错如下:
[22:39:57 root@rocky8 ~]#nginx
-bash: /usr/sbin/nginx: 没有那个文件或目录
[22:42:40 root@rocky8 ~]#cd /apps/nginx/sbin/
[22:45:18 root@rocky8 sbin]#ls
nginx.old
[22:45:18 root@rocky8 sbin]#ll
总用量 7420
-rwxr-xr-x 1 root root 7596408 6月 9 22:04 nginx.old
[22:45:31 root@rocky8 sbin]#mv nginx.old nginx
[22:45:46 root@rocky8 sbin]#ls
nginx
[22:45:47 root@rocky8 sbin]#ll
总用量 7420
-rwxr-xr-x 1 root root 7596408 6月 9 22:04 nginx
[22:46:48 root@rocky8 sbin]#nginx -s reload
[22:46:58 root@rocky8 sbin]#nginx -v
nginx version: nginx/1.18.0
[22:47:12 root@rocky8 sbin]#ps auxf | grep nginx
root 13972 0.0 0.0 12348 1124 pts/0 S+ 22:51 0:00 \_ grep --color=auto nginx
root 10802 0.0 0.1 42592 3276 ? Ss 21:53 0:00 nginx: master process /apps/nginx/sbin/nginx
nginx 13968 0.0 0.2 77124 4756 ? S 22:46 0:00 \_ nginx: worker process
至此,nginx平滑升级与回滚操作成功!
本文来自博客园,作者:一念6,转载请注明原文链接:https://www.cnblogs.com/zeng666/articles/16387083.html

浙公网安备 33010602011771号