Nginx的平滑升级和回滚

一、Nginx平滑升级和回滚

1.平滑升级流程

(1)平滑升级的四个阶段

  • 只用旧版本nginx和master和worker
  • 旧版和新版nginx的master和worker进程并存,由旧版本nginx接受处理用户的新请求
  • 旧版和新版nginx的master和worker进程并存,由新版nginx接收处理用户的新请求
  • 只有新版nginx的master和worker进程

Nginx的平滑升级和回滚_第1张图片
(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,java,服务器)