首先让咱们了解一下各类信号的意义,咱们后面会用到其中的几个:nginx
TERM,INT 快速退出日志
QUIT 优雅退出(等待全部链接关闭后再退出程序,不接受新的链接)code
HUP 在修改配置后,以新的配置启动worker进程,优雅退出旧的worker进程进程
USR1 从新打开日志文件源码
USR2 更新二进制文件编译
WINCH 优雅地关闭worker进程(但不关闭master)ast
接下来是步骤:配置
这一步很简单,新版本Nginx或者旧版本Nginx源码加上新的编译参数,在通过configure
和make
后,咱们在源码目录下的objs目录中找到新的nginx二进制文件。二进制
注意,接下来请不要make install
。请求
将旧的nginx二进制文件备份一下:
cd /usr/local/nginx/sbin mv nginx nginx.old
而后将上一步获得的新版本二进制文件复制过来:
cp /path/to/source/nginx /usr/local/nginx/sbin/
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进程来“优雅”地关闭旧的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。
快速回退的方法见最后。
升级很成功,新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。
若是咱们在发送WINCH给旧master进程后发现新master没法正常工做,咱们须要可以快速回退。
咱们通常用两种方案来快速回退。