nginx进程管理之master进程

nginx分为single和 master两种进程模型。master模型为一个master模型和n个worker进程的工作方式 。本文分析nginx的 master进程做了哪些事情,它是如何管理好各个worker进程的。

在main函数中完成了nginx启动初始化过程,启动初始化过程中的一个重要环节就是解析配置文件,回调各个配置指令的回调函数,因此完成了各个模块的配置相互关联。在完成初始化后,就调用ngx_master_process_cycle,这个函数具体做了什么事情。

    sigemptyset(&set);
    sigaddset(&set, SIGCHLD);
    sigaddset(&set, SIGALRM);
    sigaddset(&set, SIGIO);
    sigaddset(&set, SIGINT);
    sigaddset(&set, ngx_signal_value(NGX_RECONFIGURE_SIGNAL));
    sigaddset(&set, ngx_signal_value(NGX_REOPEN_SIGNAL));
    sigaddset(&set, ngx_signal_value(NGX_NOACCEPT_SIGNAL));
    sigaddset(&set, ngx_signal_value(NGX_TERMINATE_SIGNAL));
    sigaddset(&set, ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
    sigaddset(&set, ngx_signal_value(NGX_CHANGEBIN_SIGNAL));

    if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) {
        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                      "sigprocmask() failed");
    }
上面屏蔽一系列的信号,以防创建worker进程时,被打扰。

    ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);

    ngx_start_worker_processes(cycle, ccf->worker_processes,
                               NGX_PROCESS_RESPAWN);
    ngx_start_cache_manager_processes(cycle, 0);
这里开始创建worker子进程,master进程就是通过依次调用这两个函数来创建子进程。第一个调用的函数创建的子进程称为worker进程,第二个调用的函数创建的就是有关cache的子进程。接收请求,完成响应的就是worker进程。

    for (i = 0; i < n; i++) {

        ngx_spawn_process(cycle, ngx_worker_process_cycle,
                          (void *) (intptr_t) i, "worker process", type);

        ch.pid = ngx_processes[ngx_process_slot].pid;
        ch.slot = ngx_process_slot;
        ch.fd = ngx_processes[ngx_process_slot].channel[0];

        ngx_pass_open_channel(cycle, &ch);
    }
此处就是循环创建n个worker进程,fork新进程的具体工作在ngx_spawn_process函数中完成。这里涉及到一个全局数组ngx_processes(src/os/unix/ngx_process.c),数组的长度为NGX_MAX_PROCESSES(默认为 1024),存储的元素类型是ngx_process_t(src/os/uninx/ngx_process.h文件)。全局数组ngx_processes就是用来存储每个子进程的相关信息,如pid,channel,进程做具体事情的接口指针等,这 些信息就是用结构体ngx_process_t来描述的。在ngx_spawn_process创建好一个worker进程返回 后,master进程就将worker进程的pid,worker进程在ngx_processes数组中的位置及channel[0]传递给前面创建好的worker进程,然后循环创建下一个worker进程。channel是用socketpair创建的,用于进程间通信。master和worker进程以及worker进程之间都可以通过这样的一个通道进行通信。

ngx_start_cache_manager_processes函数和start_worker的工作相关无几。接着master进程就陷入死循环中守护着worker进程。在master_cycle中调用了sigsuspend,因而master进程挂起,等待信号的产生(收到信号,调用信号处理函数,设置对应的全局变量,sigsuspend函数返回,判断全局变量并采取相应的动作)

        if (ngx_quit) {
            ngx_signal_worker_processes(cycle,
                                        ngx_signal_value(NGX_SHUTDOWN_SIGNAL));

            ls = cycle->listening.elts;
            for (n = 0; n < cycle->listening.nelts; n++) {
                if (ngx_close_socket(ls[n].fd) == -1) {
                    ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
                                  ngx_close_socket_n " %V failed",
                                  &ls[n].addr_text);
                }
            }
            cycle->listening.nelts = 0;

            continue;
        }
对SIGQUIT信号进行的处理动作。调用ngx_signal_worker_processes函数向每个worker进程递送SIGQUIT信号,通知worker进程退出工作,然后关闭所有的监听套接字。用continue是为了子进程发送SIGCHLD信号给master进程,让master进程为其善后。 

        if (ngx_reap) {
            ngx_reap = 0;
            ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "reap children");

            live = ngx_reap_children(cycle);
        }
此时,ngx_reap为1,master进程调用ngx_reap_children处理所有的worker进程。

master进程就这些。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kgduu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值