# Nginx 重载流程解析

修改 nginx.conf 配置文件后,可以执行下面的指令,实现重载。这样 nginx 在不停止服务的情况下,启用了新的配置。

nginx -s reload

# Nginx 重载流程

# 向master进程发送HUP信号(reload命令)

在我们修改nginx.conf后,我们在nginx命令行执行 nginx -s reload 命令。其实是向向master进程发送HUP信号。

# master进程校验配置语法是否正确

通常我们在执行 nginx -s reload 之前先执行 -t 检验下语法是否正确。实际上master进程收到信号以后,会校验校验配置语法是否正确。所以,我们并不需要一定先先进行配置语法检测。

# master进程打开新的监听端口

在配置语法检测正确以后,nginx的master进程就会去打开新的监听窗口。

为什么要在master进程中打开新的监听窗口呢?

因为我们可能在 nginx.conf 中引入了新的例如443,或者之前我们没有打开的监听窗口,所有的worker进程是master进程的子进程,子进程会继承父进程所有已经打开的端口,这是Linux操作系统所定义的。

# master进程用新配置启动新的worker子进程

master进程用新的 nginx.conf 配置文件启动新的worker子进程

# master进程向老worker子进程发送QUIT信号

在启动新的子进程以后,再向老的worker子进程发送 QUIT 信号,QUIT 信号是请优雅地关闭子进程。

同时,我们要注意为了保障nginx服务平滑过度,一定要先启动新的worker子进程处理新的请求,再向老的worker子进程发送 QUIT信号。

# 老worker进程关闭监听句柄,处理完当前连接后结束进程

老的worker子进程收到 QUIT 信号以后,首先关闭监听句柄,也就是说这个时候新的请求由新的worker子进程处理,所以虽然它们之间有个时间差,但是时间差是非常小的。老worker进程关闭监听句柄,处理完当前连接后结束进程。

# 异常处理

在某些异常情况下,老的worker进程在处理请求时,如果有一些请求出问题了,客户端长时间没有处理,就会导致老的worker进程一直存在,无法正常的结束进程。

当然新的连接已经跑在新的worker子进程中了,所以影响不会很大。

在nginx比较新的版本中,提供了一个配置项 worker shutdown timeout ,master进程在启动新的worker子进程时,会给老的worker子进程加一个 worker shutdown timeout 定时器,如果时间到了老的worker子进程还没退出,就立刻强制的把老的worker子进程退出。从而,解决了老的worker子进程无法正常退出的问题。

# 参考

更新时间: 9/22/2020, 3:49:41 AM