# 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进程可以正常的退出。

# 参考

更新时间: 9/22/2020, 5:04:15 AM