nginx进程管理之master进程

来源:互联网 发布:工作日记软件 编辑:程序博客网 时间:2024/06/05 07:36

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进程就这些。


0 0
原创粉丝点击