菜鸟nginx源码剖析架构篇(二) nginx进程模型

菜鸟nginx源码剖析架构篇(二) nginx进程模型

 

  • Author:Echo Chen(陈斌)

  • Email:chenb19870707@gmail.com

  • Blog:Blog.csdn.net/chen19870707

  • Date:Nov 17th, 2014

     

    1.nginx进程模型

    nginx采用的是多进程模型,典型的master-worker方式,采用一个master process(监控进程,也叫做主进程)和多个woker process(工作进程)的设计方式,此外,还有1个可选的chache manager和 1 个可选的cache loader进程。

    aaaa

    这样设计的好处:
    • (1)利用多核系统的并发处理能力;

    • (2)负载均衡;

    • (3)管理进程会负责监控工作进程的状态,并负责管理其行为。

     

    2. master-worker 启动流程

    启动nginx的主进程将充当master进程,而由主进程fork()出来的子进程则充当工作进程。nginx也可以单进程模型执行,在这种进程模型下,主进程就是工作进程,没有监控进程。

    Nginx的核心进程模型框图如下:

  • 20130704111632187

    3.master进程是如何工作的

     
    监控进程充当整个进程组与用户的交互接口,同时对进程进行监护。它不需要处理网络事件,不负责业务的执行,只会通过管理worker进程来实现重启服务、平滑升级、更换日志文件、配置文件实时生效等功能。
    其工作流程如下图,它首先fork出worker进程,然后进入for循环,在每一帧循环中调用sigsupend挂起等待信号,如果收到信号,就处理信号,改变响应的标志位,然后根据标志位做出相应的操作。

    主进程

     

    master进程的标志位有如下7个:

       1: sig_atomic_t ngx_reap;
       2: sig_atomic_t ngx_terminate;
       3: sig_atomic_t ngx_quit;
       4: sig_atomic_t ngx_reconfigure;
       5: sig_atomic_t ngx_reopen;
       6: sig_atomic_t ngx_change_binary;
       7: sig_atomic_t ngx_noaccept;
     
    每个标志与信号位的及作用的对应关系如下表:
    QQ图片20141118095947

    这样,master进程的运行情况如下图:

    QBN1VA[_XEM~YN$E%R_G}%W

    下面看一下核心代码:

    3.1 master进程住循环函数 ngx_master_process_cycle

       1: void
       2: ngx_master_process_cycle(ngx_cycle_t *cycle)
       3: {
          
       4:     char              *title;
       5:     u_char            *p;
       6:     size_t             size;
       7:     ngx_int_t          i;
       8:     ngx_uint_t         n, sigio;
       9:     sigset_t           set;
      10:     struct itimerval   itv;
      11:     ngx_uint_t         live;
      12:     ngx_msec_t         delay;
      13:     ngx_listening_t   *ls;
      14:     ngx_core_conf_t   *ccf;
      15:  
      16:     //设置屏蔽信号
      17:     sigemptyset(&set);
      18:     sigaddset(&set, SIGCHLD);
      19:     sigaddset(&set, SIGALRM);
      20:     sigaddset(&set, SIGIO);
      21:     sigaddset(&set, SIGINT);
      22:     sigaddset(&set, ngx_signal_value(NGX_RECONFIGURE_SIGNAL));
      23:     sigaddset(&set, ngx_signal_value(NGX_REOPEN_SIGNAL));
      24:     sigaddset(&set, ngx_signal_value(NGX_NOACCEPT_SIGNAL));
      25:     sigaddset(&set, ngx_signal_value(NGX_TERMINATE_SIGNAL));
      26:     sigaddset(&set, ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
      27:     sigaddset(&set, ngx_signal_value(NGX_CHANGEBIN_SIGNAL));
      28:  
      29:     if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) {
          
      30:         ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
      31:                       "sigprocmask() failed");
      32:     }
      33:  
      34:     sigemptyset(&set);
      35:  
      36:  
      37:     size = sizeof(master_process);
      38:  
      39:     for (i = 0; i < ngx_argc; i++) {
          
      40:         size += ngx_strlen(ngx_argv[i]) + 1;
      41:     }
      42:  
      43:     title = ngx_pnalloc(cycle->pool, size);
      44:  
      45:     p = ngx_cpymem(title, master_process, sizeof(master_process) - 1);
      46:     for (i = 0; i < ngx_argc; i++) {
          
      47:         *p++ = ' ';
      48:         p = ngx_cpystrn(p, (u_char *) ngx_argv[i], size);
      49:     }
      50:  
      51:     ngx_setproctitle(title);
      52:  
      53:  
      54:     ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
      55:  
      56:     //其中包含了fork产生子进程的内容
      57:     ngx_start_worker_processes(cycle, ccf->worker_processes,
      58:                                NGX_PROCESS_RESPAWN);
      59:     //Cache管理进程与cache加载进程的主流程
      60:     ngx_start_cache_manager_processes(cycle, 0);
      61:  
      62:     ngx_new_binary = 0;
      63:     delay = 0;
      64:     sigio = 0;
      65:     live = 1;
      66:  
      67:     for ( ;; ) {
          //循环
      68:         if (delay) {
          
      69:             if (ngx_sigalrm) {
          
      70:                 sigio = 0;
      71:                 delay *= 2;
      72:                 ngx_sigalrm = 0;
      73:             }
      74:  
      75:             ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
      76:                            "termination cycle: %d", delay);
      77:  
      78:             itv.it_interval.tv_sec = 0;
      79:             itv.it_interval.tv_usec = 0;
      80:             itv.it_value.tv_sec = delay / 1000;
      81:             itv.it_value.tv_usec = (delay % 1000 ) * 1000;
      82:  
      83:             if (setitimer(ITIMER_REAL, &itv, NULL) == -1) {
          
      84:                 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
      85:                               "setitimer() failed");
      86:             }
      87:         }
  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值