以前咱们讲解 Nginx 命令行的时候,能够看到 Nginx 中止有两种方式,分别是 nginx -s quit
和 nginx -s stop
,其中 stop 是指当即中止 Nginx,而 quit 是指优雅的关闭 Nginx,对应的信号也是一样的,还有咱们以前提到的 reload 和热升级这样的过程当中都涉及到了优雅的中止 Nginx。nginx
那所谓的优雅的中止 Nginx 到底是怎样一个过程呢,接下来让我一块儿来学习下吧。web
所谓的优雅的关闭,是针对 worker 进程而言的,由于只有 worker 进程 才会处理请求。若是咱们在处理一个链接的时候,无论链接此时对于请求是怎样一个做用,直接去关闭连接会致使用户收到错误,因此优雅地关闭就是指 Nginx 的 worker 进程 能够识别出当前链接没有正在处理请求,这个时候再把链接进行关闭。websocket
对于某些请求 Nginx 没法作到优雅地关闭 worker 进程,好比当 Nginx 代理 websocket 协议的时候,在 websocket 后面进行通信的 frame 桢里面,Nginx 是不解析他的桢的;Nginx 作 TCP 层或者 UDP 层反向代理的时候,也没有办法识别一个请求须要经历多少报文才算是结束;可是对于 HTTP 请求,Nginx 能够作到,因此优雅地关闭主要针对的是 HTTP 请求。socket
接下来咱们去看一下优雅地关闭 worker 进程都有哪些流程。学习
首先第一步会设置一个定时器,在 nginx.conf 中能够配置一个 worker_shutdown_timeout,配置完 worker_shutdown_timeout 以后,会加一个标志位,表示进入优雅关闭流程了。ui
第二步会先关闭监听句柄,要保证所在的 worker 进程不会再去处理新的链接。命令行
接下来会先去看链接池,由于 Nginx 为了保证对资源的利用是最大化的,常常会保存一些空闲的链接,可是没有断开,这时候会首先关闭空闲链接。代理
第四步是可能很是耗时的一步,由于 Nginx 不是主动的马上关闭,是经过第一步添加的标志位,而后在循环中每当发现一个请求处理完毕,就会把这个请求使用的链接关掉,因此在循环中等待关闭全部的时间可能会很长。当设置了 worker_shutdown_timeout 的时候,即便请求还没处理完,当时间到了以后这些请求都会被强制关闭,也就是说优雅地关闭只完成了一半,有一部分链接是当即中止的。code
所以在如下两个条件:当全部循环中链接被优雅地关闭,或者达到了 worker_shutdown_timeout 时间定时器之后,worker 进程都会当即退出。blog
这篇文章主要讲解了 worker 进程优雅关闭的一个过程,不少时候咱们都会用到 Nginx 优雅关闭这样一个特性,那么在这一个特性失效的时候,咱们须要考虑 Nginx 有没有能力去断定一个链接此时应当被正确的关掉;或者说若是出现了错误、有些模块或者有些客户端不能正常的处理请求时,Nginx 须要有一些例外的措施,好比 worker_shutdown_timeout 来保证 Nginx 老的 worker 进程能够正常的退出掉。