# Nginx 优雅地关闭worker进程
优雅地关闭就是指nginx的worker进程可以识别出当前的连接没有正在处理请求,这个时候,我们再把连接进行关闭。
# 限制条件
对于有些请求nginx是做不到优雅地关闭的。
比如说当nginx代理websocket协议的时候,在websocket后面进行通讯的freem帧里面,nginx是不解析它的帧的,所以这个时候它是没有办法的。nginx做TCP层或者UDP层反向代理的时候,它也没法识别一个请求需要经历多少报文才算是结束。
但是对于http请求,nginx可以做到。所以优雅地关闭,我们主要是针对http请求。
# 流程说明
# 设置定时器worker_shutdown_timeout
在nginx.conf中,我们可以配置一个 worker_shutdown_timeout
。
设置完定时器以后,它会加一个标志位,就是表示现在进入优雅地关闭这样一套流程了。
# 关闭监听句柄
保证需要关闭的worker进程不再去处理新的请求了。
# 关闭空闲连接
接下来nginx会去先看它的连接池,因为nginx实际上为了保证自己对资源利用是最大化的,它经常会保存一些空闲的连接,但是没有断开。这时候会首先关闭所有的空闲的连接。
# 在循环中等待全部连接关闭
这可能是时间非常长的一步,因为nginx不是主动的立刻的关闭,所以它通过第一步我们加的标志位,那么在循环中,每当发现一个请求处理完毕就会把这个请求使用的连接关掉。
在循环中等待全部连接关闭的时间可能会超过第一步我们说的 worker_shutdown_timeout
。当我们设置了 worker_shutdown_timeout
以后,即使请求还没有处理完,这些连接就会被强制关闭。也就是说优雅的额关闭只完成了一半,有一部分连接变成了立即停止。
所以,在处理循环中,请求处理完毕了或者达到了 worker_shutdown_timeout
定时器条件以后,worker进程都会立即退出。
# 退出进程
最后是退出进程
# 总结
当优雅的关闭失效的时候,我们需要考虑nginx是否有能力去判定一个连接此时应当被正确的关掉。或者说有一些模块出现了错误,或者有一些客户端不能处理请求时,我们可以设置 worker_shutdown_timeout
来保证nginx老的worker进程可以正常的退出。