一、Nginx平滑升级和回滚
1.平滑升级流程
(1)平滑升级的四个阶段
- 只用旧版本nginx和master和worker
- 旧版和新版nginx的master和worker进程并存,由旧版本nginx接受处理用户的新请求
- 旧版和新版nginx的master和worker进程并存,由新版nginx接收处理用户的新请求
- 只有新版nginx的master和worker进程
(2)具体过程
- 存在旧版nginx时,编译安装新版本,生成新版的二进制文件
- 用新nginx程序文件替换nginx二进制文件(注意备份旧版本的二进制文件,必要时回滚)
- 向旧版本的master进程发送USR2信号启动新nginx进程
master进程修改pid文件名加上后缀.oldbin,成为nginx.pid.oldbin
将新生成的master进程的PID存放至新生成的pid文件nginx.pid
master进程用心nginx二进制文件启动新master进程及worker子进程成为旧master的子进程
系统中将有新旧两个nginx主进程和对应的worker子进程并存
当前新的请求仍然由旧nginx的worker进程进行处理- 向旧的nginx服务进程发送WINCH信号,使旧的nginx worker进程平滑停止,旧的nginx worker进程将不再接收新请求
当前新的请求由新nginx的worker进程处理
旧的nginx master进程仍然存在
测试访问确认新版本是否正常工作- 如果发现升级正常,向旧master进程发送QUIT信号,关闭旧master,并删除nginx.pid.oldbin文件,到此旧版本的nginx彻底下线,新版本正式上线
- 如果发现升级有问题,可以回滚:向旧master发送HUP,旧版本的worker开始接收新请求,向新master发送QUIT
(3)实现过程
#下载最新稳定版
说明:
- 编译安装时,./configure 编译的参数使用旧版本编译的参数,可在在旧版本参数的基础上直接添加新的的参数编译。使用nginx -V 命令查看旧版本编译参数。
- 只执行make,不执行make install
[root@unbunt2204 ~]#wget https://nginx.org/download/nginx-1.24.0.tar.gz
[root@unbunt2204 ~]#tar xf nginx-1.24.0.tar.gz -C /usr/local/src/
[root@unbunt2204 ~]#cd /usr/local/src/
[root@unbunt2204 src]#ls
nginx-1.22.1 nginx-1.22.1.tar.gz nginx-1.24.0
[root@unbunt2204 src]#nginx -V
nginx version: nginx/1.22.1
built by gcc 11.4.0 (Ubuntu 11.4.0-1ubuntu1~22.04)
built with OpenSSL 3.0.2 15 Mar 2022
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
[root@unbunt2204 src]#cd nginx-1.24.0/
[root@unbunt2204 nginx-1.24.0]#./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
[root@unbunt2204 nginx-1.24.0]#make
[root@unbunt2204 nginx-1.24.0]#objs/nginx -v
nginx version: nginx/1.24.0
[root@unbunt2204 nginx-1.24.0]#/apps/nginx/sbin/nginx -v
nginx version: nginx/1.22.1
#将旧版的nginx命令备份
说明:
- 将旧版本备份后,用新版本的nginx命令覆盖旧版本程序时,注意:需要加 -f 选项强制覆盖
- 覆盖后检测新的版本和配置文件语法兼容性 使用nginx -t命令
[root@unbunt2204 nginx-1.24.0]#cp /apps/nginx/sbin/nginx /opt/nginx.old -a
[root@unbunt2204 nginx-1.24.0]#ls /opt
nginx.old
[root@unbunt2204 nginx-1.24.0]#cp -f objs/nginx /apps/nginx/sbin/nginx
[root@unbunt2204 nginx-1.24.0]#ll /apps/nginx/sbin/nginx
-rwxr-xr-x 1 root root 5929496 Jun 17 12:09 /apps/nginx/sbin/nginx*
[root@unbunt2204 nginx-1.24.0]#/apps/nginx/sbin/nginx -v
nginx version: nginx/1.24.0
[root@unbunt2204 nginx-1.24.0]#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
#使用客户端持续向nginx发送请求(观察测试)
说明:
- 若客户端请求在平滑升级中始终没有收到影响说明平滑升级成功
[root@unbunt2204 ~]#dd if=/dev/zero of=/apps/nginx/html/test.img bs=1M count=10
[root@rocky8 ~]# wget --limit-rate=1k http://10.0.0.201/test.img
--2024-06-17 20:00:23-- http://10.0.0.201/test.img
Connecting to 10.0.0.201:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 10485760 (10M) [application/octet-stream]
Saving to: ‘test.img’
test.img 0%[> ] 1.59M 1.00KB/s eta 2h 23m
#开始平滑升级发送USR2信号
说明:
- 发送信号USR2 平滑升级可执行程序,将存储有旧版本主进程PID的文件重命名为nginx.pid.oldbin,并启动新的nginx
- 此时两个master的进程都在运行,只是旧的master不在监听,由新的master监听80
- 此时Nginx开启一个新的master进程,且这个新master进程会生成新的worker进程,即升级后的Nginx进程,此时老的进程不会自动退出,新的请求仍由旧进程处理。
- 如果有新请求,仍由旧版本提供服务
[root@unbunt2204 nginx-1.24.0]#kill -USR2 `cat /apps/nginx/logs/nginx.pid`
[root@unbunt2204 ~]#ps aux | grep nginx
root 5249 0.0 0.0 10168 904 ? Ss 11:37 0:00 nginx: master process /apps/nginx/sbin/nginx
nginx 5250 0.0 0.1 10904 3904 ? S 11:37 0:00 nginx: worker process
root 19864 0.0 0.3 10180 6348 ? S 12:15 0:00 nginx: master process /apps/nginx/sbin/nginx
nginx 19865 0.0 0.1 10916 3664 ? S 12:15 0:00 nginx: worker process
root 19870 0.0 0.1 4024 2016 pts/4 R+ 12:16 0:00 grep --color=auto nginx
[root@unbunt2204 ~]#lsof -i :80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nginx 5249 root 6u IPv4 40931 0t0 TCP *:http (LISTEN)
nginx 5250 nginx 3u IPv4 48319 0t0 TCP bogon:http->bogon:49504 (ESTABLISHED)
nginx 5250 nginx 6u IPv4 40931 0t0 TCP *:http (LISTEN)
nginx 19864 root 6u IPv4 40931 0t0 TCP *:http (LISTEN)
nginx 19865 nginx 6u IPv4 40931 0t0 TCP *:http (LISTEN)
[root@unbunt2204 ~]#curl -I http://10.0.0.201
HTTP/1.1 200 OK
Server: nginx/1.22.1
Date: Mon, 17 Jun 2024 12:01:49 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Mon, 17 Jun 2024 11:29:26 GMT
Connection: keep-alive
ETag: "66701e16-267"
Accept-Ranges: bytes
#发送WINCH信号
说明:
- 先关闭旧nginx的worker进程,而不关闭旧nginx主进程方便回滚
- 向原老的Nginx主进程发送WINCH信号,它会平滑关闭老的工作进程(主进程不退出),这时所有新请求都会由新版Nginx处理
- 如果旧版worker进程有用户的旧的请求,会一直等待处理完后才会关闭,即平滑关闭
- 如果有新请求,由新版本提供服务
[root@unbunt2204 nginx-1.24.0]#kill -WINCH `cat /apps/nginx/logs/nginx.pid.oldbin`
[root@unbunt2204 ~]#ps aux | grep nginx
root 5249 0.0 0.0 10168 904 ? Ss 11:37 0:00 nginx: master process /apps/nginx/sbin/nginx
nginx 5250 0.0 0.1 10904 3904 ? S 11:37 0:00 nginx: worker process is shutting down
root 19864 0.0 0.3 10180 6348 ? S 12:15 0:00 nginx: master process /apps/nginx/sbin/nginx
nginx 19865 0.0 0.2 10916 4220 ? S 12:15 0:00 nginx: worker process
root 20015 0.0 0.1 4024 2004 pts/4 S+ 12:27 0:00 grep --color=auto nginx
#发送QUIT信号升级成功
说明:
- 经过一段时间测试,新版本服务没问题,最后发送QUIT信号,退出老的master,完成全部升级过程
- 如果有旧的连接,不会立即关闭旧版本的Master和对应的Worker进程,直到所有旧连接断开,才会关闭所的旧的进程
[root@unbunt2204 nginx-1.24.0]#kill -QUIT `cat /apps/nginx/logs/nginx.pid.oldbin`
[root@unbunt2204 ~]#ps aux | grep nginx
root 5249 0.0 0.0 10168 904 ? Ss 11:37 0:00 nginx: master process /apps/nginx/sbin/nginx
nginx 5250 0.0 0.1 10904 3904 ? S 11:37 0:00 nginx: worker process is shutting down
root 19864 0.0 0.3 10180 6348 ? S 12:15 0:00 nginx: master process /apps/nginx/sbin/nginx
nginx 19865 0.0 0.2 10916 4220 ? S 12:15 0:00 nginx: worker process
root 20015 0.0 0.1 4024 2004 pts/4 S+ 12:27 0:00 grep --color=auto nginx
[root@unbunt2204 ~]#nginx -v
nginx version: nginx/1.24.0
#就连接关闭后
[root@unbunt2204 ~]#ps aux | grep nginx
root 19864 0.0 0.3 10180 6348 ? S 12:15 0:00 nginx: master process /apps/nginx/sbin/nginx
nginx 19865 0.0 0.2 10916 4220 ? S 12:15 0:00 nginx: worker process
root 20017 0.0 0.1 4024 2016 pts/4 S+ 12:27 0:00 grep --color=auto nginx
#重新发送HUP信号回滚
说明:
- 在发送WINCH信号后,如果升级的新版本发现问题需要回滚,可以发送HUP信号,重新拉起旧版本的worker
- 最后关闭新版的master和worker,如果不执行上面的HUP信号,QUIT信号也可以重新拉起旧版本的worker进程
- 此时nginx版本命令依旧是新版本
[root@unbunt2204 ~]#kill -HUP `cat /apps/nginx/logs/nginx.pid.oldbin`
[root@unbunt2204 ~]#ps aux | grep nginx
root 5249 0.0 0.0 10168 904 ? Ss 11:37 0:00 nginx: master process /apps/nginx/sbin/nginx
root 19864 0.0 0.3 10180 6348 ? S 12:15 0:00 nginx: master process /apps/nginx/sbin/nginx
nginx 19865 0.0 0.2 10916 4220 ? S 12:15 0:00 nginx: worker process
nginx 20099 0.0 0.1 10904 3628 ? S 12:29 0:00 nginx: worker process
root 20101 0.0 0.1 4024 2004 pts/10 S+ 12:29 0:00 grep --color=auto nginx
[root@unbunt2204 ~]#kill -QUIT `cat /apps/nginx/logs/nginx.pid`
[root@unbunt2204 ~]#/apps/nginx/sbin/nginx -v
nginx version: nginx/1.24.0
#用备份的旧版本nginx二进制文件覆盖新版本nginx二进制文件
[root@unbunt2204 ~]#nginx -s quit
[root@unbunt2204 ~]#cp -f /opt/nginx.old /apps/nginx/sbin/nginx
[root@unbunt2204 ~]#systemctl status nginx
[root@unbunt2204 ~]#nginx -v
nginx version: nginx/1.22.1
标签:回滚,nginx,--,0.0,平滑,Nginx,master,root,unbunt2204
From: https://blog.csdn.net/cghcgyhbc/article/details/139752940