每一年都奔走在自己de热爱里

愿你天黑有灯,下雨有伞

经典案例-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平滑升级与回滚操作成功!

posted @ 2022-06-17 21:27  一念6  阅读(135)  评论(0编辑  收藏  举报