nginx进程管理之worker进程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wuli2496/article/details/42986297

主要分析一下worker进程的情况。首先找到worker进程的入口-ngx_worker_process_cycle。这个函数不仅是worker进程的入口函数,而且是worker进程 循环工作的主要函数。

首先将全局变量ngx_process设置为worker进程的标志,然后调用ngx_worker_process_init,对worker进程作初始化操作。先看看worker进程的初始化过程。

    if (ngx_set_environment(cycle, NULL) == NULL) {
        /* fatal */
        exit(2);
    }
上面是设置相应的环境变量。接着就是设置一些资源的限制,id等参数。

    for (i = 0; ngx_modules[i]; i++) {
        if (ngx_modules[i]->init_process) {
            if (ngx_modules[i]->init_process(cycle) == NGX_ERROR) {
                /* fatal */
                exit(2);
            }
        }
    }
上面代码是循环调用每个模块的init_process,完成每个模块的进程初始化操作。调用init_process的模块比较少,只有ngx_event_process_init、ngx_google_perftools_worker、ngx_http_perl_init_worker、ngx_http_userid_init_worker。

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

        if (ngx_processes[n].pid == -1) {
            continue;
        }

        if (n == ngx_process_slot) {
            continue;
        }

        if (ngx_processes[n].channel[1] == -1) {
            continue;
        }

        if (close(ngx_processes[n].channel[1]) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "close() channel failed");
        }
    }
上面代码主要是关闭其它进程的channel资源。

    if (close(ngx_processes[ngx_process_slot].channel[0]) == -1) {
        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                      "close() channel failed");
    }
因为worker进程主要是读取master进程发过来的消息,所以worker进程关闭本进程的写通道,只保留读通道。

    if (ngx_add_channel_event(cycle, ngx_channel, NGX_READ_EVENT,
                              ngx_channel_handler)
        == NGX_ERROR)
    {
        /* fatal */
        exit(2);
    }
将本worker进程的读通道加入到nginx关心的集合中,即读通道上有数据到来后,就作相应的读操作。

此处初始化结束。

    for ( ;; ) {

        if (ngx_exiting) {

            c = cycle->connections;

            for (i = 0; i < cycle->connection_n; i++) {

                /* THREAD: lock */

                if (c[i].fd != -1 && c[i].idle) {
                    c[i].close = 1;
                    c[i].read->handler(c[i].read);
                }
            }

            if (ngx_event_timer_rbtree.root == ngx_event_timer_rbtree.sentinel)
            {
                ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");

                ngx_worker_process_exit(cycle);
            }
        }

        ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle");

        ngx_process_events_and_timers(cycle);

        if (ngx_terminate) {
            ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");

            ngx_worker_process_exit(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_close_listening_sockets(cycle);
                ngx_exiting = 1;
            }
        }

        if (ngx_reopen) {
            ngx_reopen = 0;
            ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reopening logs");
            ngx_reopen_files(cycle, -1);
        }
    }
ngx_exiting是在worker进程收到SIGQUIT信号后,在worker进程退出前,处理完每个connection上发生的事件,处理完成后,进程退出。

ngx_process_events_and_timers是进程处理事件的核心。

ngx_ternimate是worker进程收到SIGINT信号后,进程退出。

ngx_quit是进程收到SIGQUIT信号,如果此时worker进程不是处于exiting状态,就将ngx_exiting设置为1,让其进入exiting状态,同时关闭监听套接口。

ngx_reopen是进程收到SIGUSR1信号。

worker进程的处理流程差不多就是这样了。


阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页