• Nginx 源码分析 模块module 解析执行 nginx.conf 配置文件流程分析 二


      接上一篇,通过关键代码段的分析、和一些关键函数的摘录对nginx 运用module 模块构架对nginx.conf 进行解析执行的流程有了一个基本认识。流程总结如下:

      1、获取全部参与编译的模块module 进行统计编号。

      2、根据module 模块的个数分配 配置信息资源的指针空间。

      3、创建NGX_CORE_MODULE 核心模块的配置信息,并将指针空间中对应模块编号的指针进行设置。

      4、初始化conf 配置信息,解析参数 ngx_conf_param ,解析配置文件 ngx_conf_parse

      

      以上第4步中解析配置文件 ngx_conf_parse 过程又可分为:

      1、获取配置文件。

      2、保存当前配置文件的上下文,并将cf->conf_file 指向当前配置文件。

      3、读取当前配置文件中的配置指令名 ngx_conf_read_token 

      4、判断读取指令的类别、是否正确。

      5、执行指令前是否进行其他处理。

      6、交给 ngx_conf_handler 处理指令。

      7、全部执行完后,恢复上下文。


      以上第6 ngx_conf_handler 过程又可分解为:

      1、查找与配置信息中指定分析模块的类别,并获取该模块的指令集。

      2、遍历指令集是否有要求处理的指令。

      3、如果匹配,判断指令类型、指令参数是否正确。

      4、执行指令对应的功能函数 set

      5、正确完成返回NGX_OK

      整个流程一环扣一环,利用其中的 cfngx_conf_t) 这个结构起到了穿针引线、传递资源的作用。分析到这里,NGX_CORE_MODULE中的指令是知道如何执行的了,但是像https{ … } events{ … }括号中的指令是如何执行的呢?它可并非属于核心模块里面的指令。我们这里以events模块进行分析。

      我们首先来看events 核心指令的一些参数

    static ngx_command_t  ngx_events_commands[] = {
    
        { ngx_string("events"),
          NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
          ngx_events_block,
          0,
          0,
          NULL },
    
          ngx_null_command
    };

      里面的 NGX_CONF_BLOCK 有没有印象?想想 ngx_conf_read_token() 里面返回的参数有NGX_CONF_BLOCK_START NGX_CONF_BLOCK_DONE 再联系下ngx_conf_handler 里面的这句:

    if ((cmd->type & NGX_CONF_BLOCK) && last != NGX_CONF_BLOCK_START) { … }

      明白了吧,这个参数的意识就代表了,它是二级模块的标示,他后面跟着的是 { 这个符号作为结束符。这个指令参数也告诉我们,解析到events 这个标识 时调用 ngx_events_block。那就来看看 ngx_events_block 吧。

    static char *
    ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
    {
        char                 *rv;
        void               ***ctx;
        ngx_uint_t            i;
        ngx_conf_t            pcf;
        ngx_event_module_t   *m;
    
        /*统计 envent 模块总数,并建立编号*/
      /* 感觉相似么? 上一篇中的 main 函数里的那段代码!! */
    ngx_event_max_module
    = 0; for (i = 0; ngx_modules[i]; i++) { if (ngx_modules[i]->type != NGX_EVENT_MODULE) { continue; } ngx_modules[i]->ctx_index = ngx_event_max_module++; } ctx = ngx_pcalloc(cf->pool, sizeof(void *)); if (ctx == NULL) { return NGX_CONF_ERROR; }
    /* 上一篇又有相似的, ngx_init_cycle 函数 里的那句!! */
    *ctx = ngx_pcalloc(cf->pool, ngx_event_max_module * sizeof(void *));
    if (*ctx == NULL) { return NGX_CONF_ERROR; } *(void **) conf = ctx;
     /*  还是 ngx_init_cycle 函数 里有相似的!!!  */
    for (i = 0; ngx_modules[i]; i++) {
            if (ngx_modules[i]->type != NGX_EVENT_MODULE) {
                continue;
            }
    
            m = ngx_modules[i]->ctx;
    
            if (m->create_conf) {
                (*ctx)[ngx_modules[i]->ctx_index] = m->create_conf(cf->cycle);
                if ((*ctx)[ngx_modules[i]->ctx_index] == NULL) {
                    return NGX_CONF_ERROR;
                }
            }
        }
    
    /* 保存原来的cf ,设置当前的cf ,这样 cf 就变成二级模块的了!!不再是核心模块了!*/ pcf
    = *cf; cf->ctx = ctx; cf->module_type = NGX_EVENT_MODULE; cf->cmd_type = NGX_EVENT_CONF;
    /* 解析二级模块指令了!用的还是
    ngx_conf_parse(上一篇) ,注意 cf 变了上面重新设置了*/
        rv = ngx_conf_parse(cf, NULL);
    /* 恢复cf */
    *cf = pcf; if (rv != NGX_CONF_OK) return rv;

      /* 初始化,
    ngx_init_cycle 函数 里也有类似的。*/
    for (i = 0; ngx_modules[i]; i++) {
            if (ngx_modules[i]->type != NGX_EVENT_MODULE) {
                continue;
            }
    
            m = ngx_modules[i]->ctx;
    
            if (m->init_conf) {
                rv = m->init_conf(cf->cycle, (*ctx)[ngx_modules[i]->ctx_index]);
                if (rv != NGX_CONF_OK) {
                    return rv;
                }
            }
        }
    
        return NGX_CONF_OK;
    }

      看完这段代码我想大家应该是熟悉的,里面很多和前一篇中摘录的代码相似,具体的在注释中也点明了 就像是一级模块解析的一个缩影。总结来说,对于像events{ .... }这样的二级模块,都有对应的ngx_XXXX_block 它在这里所做的工作就是,保存传进来的配置内容,设置二级模块需要的配置内容(再说具体一点就是配置二级模块类型,配置命令类型,重新定义上下文),然后解析括号中的二级模块指令用的还是 ngx_conf_parse 这个函数,这样一来就与一级模块指令的解析一致了。而三级模块也就类似可以解决了。至此,nginx 运用 module 模块构建对 nginx.conf 配置文件的解析过程分析就全部结束了,写些程序的时候可以借鉴下这样的模块 解析配置文件的 构架。

  • 相关阅读:
    POJ 1320 Street Numbers(佩尔方程)
    hdu 3292 No more tricks, Mr Nanguo
    佩尔方程
    hdu 4825 xor sum(字典树+位运算)
    Xor Sum 2(位运算)
    数串
    EJS
    JQuery性能优化
    常用正则
    JavaScript prototype继承中的问题
  • 原文地址:https://www.cnblogs.com/jzhlin/p/nginx_conf_2.html
Copyright © 2020-2023  润新知