我们都知道nginx进程可以通过信号来进行控制,通过对主进程PID传入以下几个信号,使nginx完成对应的操作,主进程PID通过nginx.pid文件获得,或通过ps命令查询
TERM,INT 立即关闭(停止)进程,不处理完进行中的任务
QUIT 正常关闭(停止)进程,处理完当前任务后关闭
HUP 关闭旧的子进程套接字监听,旧的子进程仍然处理在进行中的任务,处理 完成后关闭,重新读取配置文件,启动新的子进程处理新的请求
USR1 重新打开日志文件
USR2 平滑升级可执行文件
WINCH 正常关闭子进程
以上是对主进程的信号控制,虽然很少用到,但是子进程也可以通过信号来控制,支持INT、QUIT、USR1、WINCH四种信号
接着挨着看下,首先是关闭进程,看下两种不同关闭进程的区别(为了更直观,用动图的方式展示)
![46b9554b6fd388ddb99f5c887048c2d6.gif](https://i-blog.csdnimg.cn/blog_migrate/08ff7932deb8d4c64867e83c31fc541c.gif)
![5c5b287f25381f0760f1dae2ab89c2c6.gif](https://i-blog.csdnimg.cn/blog_migrate/0b5413f6ab94a3b32f52b9ff9a7d6033.gif)
可以看到,INT信号,进程直接退出,中断正在处理的进程,而QUIT信号,则在处理完已有请求后才退出
![f18dc2abc2f03de75ed9fb997329b997.gif](https://i-blog.csdnimg.cn/blog_migrate/7e20978acd27e9c3eb2b59ee5d2d8a85.gif)
HUP信号通常是做配置更新之后的操作,主进程会检查配置语法有效性,之后读取新的配置,启动新的子进程(worker进程),这里有个重要的地方,就是如果它检测语法有问题,或者用新的配置文件启动新的监听套接字的时候,如果启动失败,它会回滚更改,继续使用过旧的配置,所以这也是很多人说nginx reload之后,配置没有生效,这个是很大概率的,正常我们可以在启动前,通过nginx -t来检测配置语法,没有问题之后,再通过reload或HUP信号去重新加载配置
master进程在收到HUP信号后,旧的子进程(worker进程)不会再分配新的请求,关闭监听套接字,将现有的进程处理完毕后,退出
![709bd3b08446b7ee234a74aa3bf17f28.gif](https://i-blog.csdnimg.cn/blog_migrate/47206511b0f0cd5cdb8c3aef9deff98d.gif)
USR1信号主要是用来做日志切割或备份时用到,在logrotate中的nginx日志配置中就可以看到,实际使用的就是USR1信号,来发送到nginx.pid,在对日志重命名,备份、压缩之后,需要通过这个信号量来重新打开日志文件,并记录日志
![fa7b29a0902c0ee39ed728ba15dd760c.gif](https://i-blog.csdnimg.cn/blog_migrate/53fd76e17635995535fe7b972f8ab591.gif)
USR2信号主要是用来做版本升级的,这个是要说的重点,网上文章都是编译完新的nginx可执行文件后,通过cp,将新的可执行文件覆盖旧的可执行文件,结果可想而知,肯定是覆盖不了的,提示文件忙,因为文件在被调用,无法覆盖,然后接着让干掉所有调用nginx的进程,这有点扯了,用nginx,就是因为nginx可以平滑升级(像某巧克力一样丝滑),你让我kill掉所有nginx进程
正确的姿势是,重命名旧的nginx进程(备份),将新的nginx进程放到nginx的sbin目录下(nginx文件原来的位置),之后,通过USR2信号来平滑升级
主进程接收到USR2信号后,将pid文件重命名为.oldbin后缀的文件,然后通过新的可执行文件启动新的master进程,注意,新的master进程是由旧的master进程启动的,可以通过上图的PID看,然后新的master进程再启动新的子进程(worker进程),这个时候,旧的worker进程和新的worker进程都继续接收请求,注意,旧的工作进程并不会终止工作,仍然继续处理请求,这个时候,需要手动发送WINCH信号到旧的主进程,当然你也可以一个一个发送WINCH信号到子进程(累死你),当旧的主进程收到WINCH信号后,发送消息给旧的子进程(worker进程),要求子进程正常关闭
之后,只有新的子进程(worker进程)处理请求,但是旧的主进程不会退出,仍然工作,因为新的nginx启动后可能不正常,所以旧的主进程仍然可以帮助你回滚
当你发现新的主进程,并没有按你预想的那样,你可以发送HUP信号到旧的主进程,旧的主进程会重新启动新的子进程(worker进程),然后通过QUIT信号将新的主进程关闭,这种是比较温和的处理方式
如果你新的nginx完全无法工作,或影响比较大,那你应该用TERM信号,发送给新的主进程,让它和子进程(worker进程)立即退出,然后旧的主进程,会自动启动它的子进程(worker进程),回滚到之前的nginx版本
![a2ef7671572f2a7b2a956783a6ff1896.gif](https://i-blog.csdnimg.cn/blog_migrate/020ec047aa748f29dacc4aeb448e0ee8.gif)
当升级完成,新的主进程稳定工作,通过QUIT信号,让旧的主进程退出,升级完毕!
当然,如果是用包管理工具升级,就没有这么繁琐了
持续更新,欢迎扫码关注,敬请期待!
![b0dc3cc9434fbb1c79927301e4bf8754.png](https://i-blog.csdnimg.cn/blog_migrate/b070a0540f71d46403ebaf064e5932bb.jpeg)
Nginx通过Cookie做灰度就这么简单
Nginx处理图片,就是这么简单
Nginx中利用resolver实现动态upstream
Nginx编译安装优化