zoukankan      html  css  js  c++  java
  • Nginx得知——流程模型(worker流程)

    流程模型

    worker流程

            master进程模型核心函数ngx_master_process_cycle()中调用了创建子进程函数ngx_start_worker_processes(),该函数源代码例如以下

    static void
    ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, ngx_int_t type)
    {
        ngx_int_t      i;
        ngx_channel_t  ch;
    
        ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start worker processes");
    
        ch.command = NGX_CMD_OPEN_CHANNEL;
    	/
        for (i = 0; i < n; i++) {
    		/*ngx_spawn_process方法调用fork函数创建进程运行ngx_worker_process_cycle()函数,该函数是worker进程模型的核心*/
            ngx_spawn_process(cycle, ngx_worker_process_cycle,
                              (void *) (intptr_t) i, "worker process", type);
    		/*
    		在ngx_spawn_process创建好一个worker进程返回后,master进程就将worker进程的pid、worker
    		进程在ngx_processes数组中的位置及channel[0]传递给前面已经创建好的worker进程。然后继续
    		循环開始创建下一个worker进程。

    */ 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); } }


            在剖析ngx_worker_process_cycle是怎样工作的之前我们了解master进程和worker进程之间的通信方式:master进程是监控进程。对worker进程监控和管理。master进程採用的是信号管理worker进程。worker进程收到信号时,信号处理函数ngx_signal_handler()就会运行。

            对于worker进程的工作方法ngx_worker_process_cycle来说,它主要关注4个全局标志位:

            sig_atomic_t    ngx_terminate;        //强制关闭进程

            sig_atomic_t    ngx_quit;                 //优雅地关闭进程(有唯一一段代码会设置它。就是接受到QUIT信号。ngx_quit仅仅有在首次设置为1,时,才会将ngx_exiting置为1)

           ngx_uint_t         ngx_exiting;            //退出进程标志位

           sig_atomic_t    ngx_reopen;          //又一次打开全部文件

            当中ngx_terminate、ngx_quit 、ngx_reopen都将由ngx_signal_handler依据接受到的信号来设置,例如以下表所看到的。

    ngx_exiting标志位仅由ngx_worker_cycle方法在退出时作为标志位使用。

    信号

    相应进程中全局标志位变量

    意义

    QUIT

    ngx_quit

    优雅关闭进程

    TERM或者INT

    ngx_terminate

    强制关闭进程

    USR1

    ngx_reopen

    又一次打开全部文件

             如今我们来剖析ngx_worker_process_cycle()函数。能够对比下图来理解源码:

     

          

    static void
    ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data)
    {
        ngx_int_t worker = (intptr_t) data;
    
        ngx_uint_t         i;
        ngx_connection_t  *c;
    
        ngx_process = NGX_PROCESS_WORKER;
    	/*worker进程进入工作循环之前的初始化工作*/
        ngx_worker_process_init(cycle, worker);
    
        ngx_setproctitle("worker process");
    
    #if (NGX_THREADS)
        {
        ngx_int_t         n;
        ngx_err_t         err;
        ngx_core_conf_t  *ccf;
    
        ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
    
        if (ngx_threads_n) {
            if (ngx_init_threads(ngx_threads_n, ccf->thread_stack_size, cycle)
                == NGX_ERROR)
            {
                /* fatal */
                exit(2);
            }
    
            err = ngx_thread_key_create(&ngx_core_tls_key);
            if (err != 0) {
                ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
                              ngx_thread_key_create_n " failed");
                /* fatal */
                exit(2);
            }
    
            for (n = 0; n < ngx_threads_n; n++) {
    
                ngx_threads[n].cv = ngx_cond_init(cycle->log);
    
                if (ngx_threads[n].cv == NULL) {
                    /* fatal */
                    exit(2);
                }
    
                if (ngx_create_thread((ngx_tid_t *) &ngx_threads[n].tid,
                                      ngx_worker_thread_cycle,
                                      (void *) &ngx_threads[n], cycle->log)
                    != 0)
                {
                    /* fatal */
                    exit(2);
                }
            }
        }
        }
    #endif
    	
        for ( ;; ) {
    		/*ngx_exiting为1。在開始准备关闭worker金曾*/
            if (ngx_exiting) {
    
                c = cycle->connections;
    			
                for (i = 0; i < cycle->connection_n; i++) {
    
                    /* THREAD: lock */
    				/* 依据当前ngx_cycle_t中全部正在处理的连接。调用它们相应的关闭连接处理方法 */
                    if (c[i].fd != -1 && c[i].idle) {
                        c[i].close = 1;
                        c[i].read->handler(c[i].read);
                    }
                }
    			/*
    			若ngx_event_timer_rbtree红黑树不为空表示还有事件须要处理。
    			否则,调用ngx_worker_process_exit,以调用全部模块的exit_process方法,销毁内存池
    			*/
                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");
    			/*调用全部模块的exit_process方法,销毁内存池*/
                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_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);
            }
        }
    }
    

    转载请注明出处,谢谢~~

    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    AtCoder Grand Contest 015 题解
    AtCoder Grand Contest 014 题解
    AtCoder Grand Contest 013 题解
    AtCoder Grand Contest 012 题解
    AtCoder Grand Contest 011 题解
    AtCoder Grand Contest 010 题解
    AtCoder Grand Contest 009 题解
    NOIP2017 Day2 题解
    博客园主题备份
    多项式全家桶
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4874825.html
Copyright © 2011-2022 走看看