【Nginx】不中断现有连接,平滑升级Nginx

首先让我们了解一下各种信号的意义,我们后面会用到其中的几个:

TERM,INT 快速退出

QUIT 优雅退出(等待所有连接关闭后再退出程序,不接受新的连接)

HUP 在修改配置后,以新的配置启动worker进程,优雅退出旧的worker进程

USR1 重新打开日志文件

USR2 更新二进制文件

WINCH 优雅地关闭worker进程(但不关闭master)

接下来是步骤:

1. 编译、获得新的二进制文件

这一步很简单,新版本Nginx或者旧版本Nginx源码加上新的编译参数,在经过configuremake后,我们在源码目录下的objs目录中找到新的nginx二进制文件。

注意,接下来请不要make install

2. 备份与替换

将旧的nginx二进制文件备份一下:

cd /usr/local/nginx/sbin
mv nginx nginx.old

然后将上一步得到的新版本二进制文件复制过来:

cp /path/to/source/nginx /usr/local/nginx/sbin/

3. USR2、WINCH与QUIT

发送USR2信号给master进程
kill -USR2 `cat /usr/local/nginx/logs/nginx.pid`

这一步发生了什么?

master进程首先重命名PID文件,在文件名后添加.oldbin后缀,比如nginx.pid会被重命名为nginx.pid.oldbin。接着依次启动新的执行文件和新的worker进程。这时候我们观察系统的进程,可以看到有两个master进程:

PID  PPID USER    %CPU   VSZ WCHAN  COMMAND
33126     1 root     0.0  1164 pause  nginx: master process /usr/local/nginx/sbin/nginx
33134 33126 nobody   0.0  1368 kqread nginx: worker process (nginx)
33135 33126 nobody   0.0  1380 kqread nginx: worker process (nginx)
33136 33126 nobody   0.0  1368 kqread nginx: worker process (nginx)
36264 33126 root     0.0  1148 pause  nginx: master process /usr/local/nginx/sbin/nginx
36265 36264 nobody   0.0  1364 kqread nginx: worker process (nginx)
36266 36264 nobody   0.0  1364 kqread nginx: worker process (nginx)
36267 36264 nobody   0.0  1364 kqread nginx: worker process (nginx)

注意这两个master进程的PID:第一个进程的PPID是1,这是旧master进程,而新master进程的PPID就是旧master进程的PID,这说明新的master来自于旧的master。

这时候,新旧两种worker同时接受连接请求。

发送WINCH给旧master

接下来,发送WINCH信号给旧的master进程来“优雅”地关闭旧的Nginx worker:

kill -WINCH `cat /usr/local/nginx/logs/nginx.pid.oldbin`

过一段时间,我们观察系统进程:

PID  PPID USER    %CPU   VSZ WCHAN  COMMAND
33126     1 root     0.0  1164 pause  nginx: master process /usr/local/nginx/sbin/nginx
36264 33126 root     0.0  1148 pause  nginx: master process /usr/local/nginx/sbin/nginx
36265 36264 nobody   0.0  1364 kqread nginx: worker process (nginx)
36266 36264 nobody   0.0  1364 kqread nginx: worker process (nginx)
36267 36264 nobody   0.0  1364 kqread nginx: worker process (nginx)

新旧两个master进程都在,但是worker都是来自于新master。

那么为什么我们不直接用-QUIT退出旧master呢?因为假如这时我们发现新worker进程因为一些原因无法接受请求,那我们就能快速启动旧Nginx。

快速回退的方法见最后。

QUIT退出旧master

升级很成功,新worker正常接受请求,那么我们就可以关掉旧master了:

kill -QUIT `cat /usr/local/nginx/logs/nginx.pid.oldbin`

观察系统进程:

PID  PPID USER    %CPU   VSZ WCHAN  COMMAND
36264     1 root     0.0  1148 pause  nginx: master process /usr/local/nginx/sbin/nginx
36265 36264 nobody   0.0  1364 kqread nginx: worker process (nginx)
36266 36264 nobody   0.0  1364 kqread nginx: worker process (nginx)
36267 36264 nobody   0.0  1364 kqread nginx: worker process (nginx)

我们看到,新master进程其PPID已经变成了1。

4. 快速回退

如果我们在发送WINCH给旧master进程后发现新master无法正常工作,我们需要能够快速回退。

我们一般用两种方案来快速回退。

  1. 发送HUP信号给旧master进程。旧master进程会在不重新读取配置文件的情况下直接启动新的worker进程。然后就可以发送QUIT信号给新master进程,使所有新进程可以优雅退出。
  2. 发送TERM信号给新master进程。新master进程发送信号关闭所有的worker进程(如果因为某些原因新的进程没有退出,就得发送KILL信号强制退出了)。当新master进程退出后,旧master进程会自动启动它的worker进程。

转载于:https://my.oschina.net/plutonji/blog/548049

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值