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

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

TERM,INT 快速退出日志

QUIT 优雅退出(等待全部链接关闭后再退出程序,不接受新的链接)code

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

USR1 从新打开日志文件源码

USR2 更新二进制文件编译

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

接下来是步骤:配置

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. USR二、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进程。
相关文章
相关标签/搜索