0
点赞
收藏
分享

微信扫一扫

nginx【14】优雅地关闭worker进程

8052cf60ff5c 2022-02-10 阅读 60

之前我们提到nginx的命令行的时候,nginx的停止有两种方式,-s quit-s stop 其中stop表示立即停止nginx,quit表示优雅的关闭nginx;对应的信号也是同样的;还有我们之前提到的 reload 和热部署;我们都使用了优雅的停掉nginx,那么所谓的优雅的停掉nginx到底是怎样的一个过程;

所谓优雅的关闭是指对worker进程而言的;因为只有worker进程才会处理请求;如果我们在处理一个连接的时候,不管连接此时对于请求是怎样一个作用,我们直接的去关闭这个连接,会导致用户收到错误;所以优雅的关闭就是指nginx的worker进程可以识别出当前的连接没有正在处理请求;这个时候我们再把连接信息关闭;那么nginx能不能做到这一点呢?

对于某些请求 Nginx 无法做到优雅地关闭 worker 进程,比如当 Nginx 代理 websocket 协议的时候,在 websocket 后面进行通讯的 frame 桢里面,Nginx 是不解析他的桢的;Nginx 做 TCP 层或者 UDP 层反向代理的时候,也没有办法识别一个请求需要经历多少报文才算是结束;但是对于 HTTP 请求,Nginx 可以做到,所以优雅地关闭主要针对的是 HTTP 请求。

那么所谓的优雅的关掉nginx到底是怎样的一个过程尼?
在这里插入图片描述
首先第一步会设置一个定时器,在 nginx.conf 中可以配置一个 worker_shutdown_timeout,配置完 worker_shutdown_timeout 之后,会加一个标志位,表示进入优雅关闭流程了。

第二步会先关闭监听句柄,要保证所在的 worker 进程不会再去处理新的连接。

接下来会先去看连接池,因为 Nginx 为了保证对资源的利用是最大化的,经常会保存一些空闲的连接,但是没有断开,这时候会首先关闭空闲连接。

第四步是可能非常耗时的一步,因为 Nginx 不是主动的立刻关闭,是通过第一步添加的标志位,然后在循环中每当发现一个请求处理完毕,就会把这个请求使用的连接关掉,所以在循环中等待关闭所有的时间可能会很长。当设置了 worker_shutdown_timeout 的时候,即使请求还没处理完,当时间到了之后这些请求都会被强制关闭,也就是说优雅地关闭只完成了一半,有一部分连接是立即停止的。

因此在以下两个条件:当所有循环中连接被优雅地关闭,或者达到了 worker_shutdown_timeout 时间定时器以后,worker 进程都会立即退出。

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

举报

相关推荐

0 条评论