优雅地关闭worker进程


  • 之前提到的nginx命令行时,nginx停止有两种方式, -s quit 和 -s stop
  • 其中stop表示理及停止nginx,而quit我们称为优雅地关闭nginx,对应的信号也是同样的。
  • 以及之前提到的reload,热部署这样的过程中,我们都使用了优雅地停止nginx。优雅地停止nginx到底是怎样的一个过程?
  • 所谓优雅地关闭是对worker进程而言的,因为只有worker进程才会处理请求
  • 如果我们在处理一个连接的时候,不管连接此时对于请求是怎样一个作用,我们直接去关闭这样一个连接,会导致用户收到错误。
  • 优雅地关闭就是指nginx的worker进程可以识别出当前的连接没有正在处理请求,这个时候,我们再把连接进行关闭。
  • 那么nginx能不能做到这一点?
  • 对于有些请求nginx是做不到的。比如说当nginx代理websocket协议的时候,在websocket后面进行通讯的freem帧里面,nginx是不解析它的帧的,所以这个时候它是没有办法的。nginx做TCP层或者UDP层反向代理的时候,它也没法识别一个请求需要经历多少报文才算是结束。但
  • 是对于http请求,nginx可以做到。所以优雅地关闭,我们主要是针对http请求。

优雅地关闭有哪些流程:

  • 设置定时器worker_shutdown_timeout
  • 之前我们提到的在nginx.conf中,我们可以配置一个worker_shutdown_timeout。
  • 设置完定时器以后,它会加一个标志位,,就是表示现在我进入优雅地关闭这样一套流程了。
  • 关闭监听句柄
  • 就是要保证worker进程不再去处理新的连接了。
  • 关闭空闲连接
  • 接下来它会去先看它的连接池,因为nginx实际上为了保证自己对资源利用是最大化的,它经常会保存一些空闲的连接,但是没有断开。这时候会首先关闭所有的空闲的连接。
  • 在循环中等待全部连接关闭
  • 这可能是时间非常长的一步,因为nginx不是主动的立刻的关闭,所以它通过第一步我们加的标志位,那么在循环中,每当发现一个请求处理完毕就会把这个请求使用的连接关掉。
  • 在循环中等待全部连接关闭的时间可能会超过第一步我们说的worker_shutdown_timeout。当我们设置了worker_shutdown_timeout以后,即使请求还没有处理完,这些连接就会被强制关闭。也就是说优雅的额关闭只完成了一般,有一部分连接变成了理及停止。
  • 所以,当两个条件,所有的循环中,连接被优雅地关闭或者达到了worker_shutdown_timeout定时器以后,worker进程都会立即退出。
  • 退出进程

  • 以上是worker进程优雅地关闭的一个过程。很多时候,我们都会使用到这样一个特性。
  • 在这样一个特性失效的时候,我们需要考虑nginx有没有能力去判定一个连接此时应当被正确的关掉,或者说出现了错误,有一些模块或者有一些客户端不能处理请求时,nginx需要有一些例外的措施,比如说worker_shutdown_timeout来保证nginx老的worker进程可以正常的退出掉。