我们执行这条命令的原因是希望 nginx 不停止服务始终在处理新的请求的同时把 nginx 的配置文件平滑的把旧的 nginx.conf 配置更新为新的 nginx.conf 配置。

这样一个功能对于 nginx 非常有必要,但是有时候我们会发现在执行 nginx -s reload 命令后,worker 子进程的数量会变多了,这是因为老的配置运行的 worker 进程长时间没有退出,当使用 stream 做四层反向代理的时候,可能这种场景会更多。

nginx reload流程
(1)向 master 进程发送 HUP 信号(reload命令)
(2)master 进程校验配置文件语法是否正确
(3)master 进程打开新的监听端口
(4)master 进程用新配置启动新的 worker 子进程
(5)master 进程向老 worker 子进程发送 QUIT 信号
(6)老 worker 进程关闭监听句柄,处理完当前连接后结束进程

1,reload nginx可以两种方式:

(1)./nginx -s reload

(2)kill -HUP masterpid  即  kill -HUP `cat /opt/ngx/logs/nginx.pid` 


2,代码流程

处理信号的全局变量数组:
ngx_signal_t  signals[] = {
    { ngx_signal_value(NGX_RECONFIGURE_SIGNAL),
      "SIG" ngx_value(NGX_RECONFIGURE_SIGNAL),
      "reload",
      ngx_signal_handler },

    { ngx_signal_value(NGX_REOPEN_SIGNAL),
      "SIG" ngx_value(NGX_REOPEN_SIGNAL),
      "reopen",
      ngx_signal_handler },

    { ngx_signal_value(NGX_NOACCEPT_SIGNAL),
      "SIG" ngx_value(NGX_NOACCEPT_SIGNAL),
      "",
      ngx_signal_handler },

    { ngx_signal_value(NGX_TERMINATE_SIGNAL),
      "SIG" ngx_value(NGX_TERMINATE_SIGNAL),
      "stop",
      ngx_signal_handler },

    { ngx_signal_value(NGX_SHUTDOWN_SIGNAL),
      "SIG" ngx_value(NGX_SHUTDOWN_SIGNAL),
      "quit",
      ngx_signal_handler },
...
}

#define NGX_SHUTDOWN_SIGNAL      QUIT
#define NGX_TERMINATE_SIGNAL     TERM
#define NGX_NOACCEPT_SIGNAL      WINCH
#define NGX_RECONFIGURE_SIGNAL   HUP

main
--ngx_get_options // ngx_signal设置为"reload",ngx_process = NGX_PROCESS_SIGNALLER;
--ngx_signal_process
    --ngx_os_signal_process // 入参的name就是ngx_signal,即"reload"
        --kill(pid, sig->signo) // 对master进程pid执行Kill -SIGHUP, 
            --ngx_signal_handler // case ngx_signal_value(NGX_RECONFIGURE_SIGNAL):
                                 //    ngx_reconfigure = 1; 
--ngx_master_process_cycle
    --ngx_start_worker_processes(cycle, ccf->worker_processes,
                                       NGX_PROCESS_JUST_RESPAWN); // 启新的worker
    --ngx_signal_worker_processes(cycle,
                                        ngx_signal_value(NGX_SHUTDOWN_SIGNAL)); // 关闭老的worker
        --kill(ngx_processes[i].pid, signo)
            --ngx_signal_handler // case ngx_signal_value(NGX_SHUTDOWN_SIGNAL):
                                 //    ngx_quit = 1;

ngx_worker_process_cycle
{
    ...
        if (ngx_quit) {
            ngx_quit = 0;
            ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0,
                          "gracefully shutting down");
            ngx_setproctitle("worker process is shutting down");

            if (!ngx_exiting) {
                ngx_exiting = 1;
                ngx_set_shutdown_timer(cycle);
                ngx_close_listening_sockets(cycle); // 关闭监听句柄
                ngx_close_idle_connections(cycle); // 关闭空闲链接
            }
        }
    ...
}
    

参考:

https://blog.csdn.net/m0_37886429/article/details/91517952

https://github.com/sumory/lor/issues/66

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐