• nginx配置数据结构及合并过程


    配置数据结构的创建过程

    初始化cycle->conf_ctx

    ngx_init_cycle()函数中根据nginx模块的数量ngx_max_module创建一个指针数组,如下。每个指针成员,对应nginx模块的配置数据结构。

    cycle->conf_ctx = ngx_pcalloc(pool, ngx_max_module * sizeof(void *));
    
    
    

    NGX_CORE_MODULE模块的配置数据结构创建

        for (i = 0; ngx_modules[i]; i++) {
            if (ngx_modules[i]->type != NGX_CORE_MODULE) {
                continue;
            }
    
            module = ngx_modules[i]->ctx;
    
            if (module->create_conf) {
                rv = module->create_conf(cycle);
                if (rv == NULL) {
                    ngx_destroy_pool(pool);
                    return NULL;
                }
                cycle->conf_ctx[ngx_modules[i]->index] = rv;
            }
        }

    其中,包括ngx_core_module和ngx_http_module。
     
    static ngx_core_module_t  ngx_core_module_ctx = {
        ngx_string("core"),
        ngx_core_module_create_conf,
        ngx_core_module_init_conf
    };
    ngx_module_t  ngx_core_module = {
        NGX_MODULE_V1,
        &ngx_core_module_ctx,                  /* module context */
        ngx_core_commands,                     /* module directives */
        NGX_CORE_MODULE,                       /* module type */
        NULL,                                  /* init master */
        NULL,                                  /* init module */
        NULL,                                  /* init process */
        NULL,                                  /* init thread */
        NULL,                                  /* exit thread */
        NULL,                                  /* exit process */
        NULL,                                  /* exit master */
        NGX_MODULE_V1_PADDING
    };
    ngx_core_module调用ngx_core_module_create_conf返回一个ngx_core_conf_t结构指针,成员包括daemon,master,worker_processes等。

    static ngx_core_module_t  ngx_http_module_ctx = {
        ngx_string("http"),
        NULL,
        NULL
    };
    ngx_module_t  ngx_http_module = {
        NGX_MODULE_V1,
        &ngx_http_module_ctx,                  /* module context */
        ngx_http_commands,                     /* module directives */
        NGX_CORE_MODULE,                       /* module type */
        NULL,                                  /* init master */
        NULL,                                  /* init module */
        NULL,                                  /* init process */
        NULL,                                  /* init thread */
        NULL,                                  /* exit thread */
        NULL,                                  /* exit process */
        NULL,                                  /* exit master */
        NGX_MODULE_V1_PADDING
    };
    ngx_http_module模块没有create_conf回调函数。

    解析http指令产生HTTP_MODULE模块配置数据

      ngx_http_conf_ctx_t         *ctx;
      ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
      *(ngx_http_conf_ctx_t **) conf = ctx;  /* conf指向ngx_http_module模块对应的配置数据结构 */
    
        ctx->main_conf = ngx_pcalloc(cf->pool,  sizeof(void *) * ngx_http_max_module);
        ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
        ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
        for (m = 0; ngx_modules[m]; m++) {
            if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
                continue;
            }
            module = ngx_modules[m]->ctx;
            mi = ngx_modules[m]->ctx_index;
            /* 调用create_xxx_conf()生成配置数据结构,并放于对应的指针数组中。 */
            if (module->create_main_conf) {  
                ctx->main_conf[mi] = module->create_main_conf(cf);
                if (ctx->main_conf[mi] == NULL) {
                    return NGX_CONF_ERROR;
                }
            }
            if (module->create_srv_conf) {
                ctx->srv_conf[mi] = module->create_srv_conf(cf);
                if (ctx->srv_conf[mi] == NULL) {
                    return NGX_CONF_ERROR;
                }
            }
            if (module->create_loc_conf) {
                ctx->loc_conf[mi] = module->create_loc_conf(cf);
                if (ctx->loc_conf[mi] == NULL) {
                    return NGX_CONF_ERROR;
                }
            }
        }

    ngx_http_core_module模块

    static ngx_http_module_t  ngx_http_core_module_ctx = {
        ngx_http_core_preconfiguration,        /* preconfiguration */
        NULL,                                  /* postconfiguration */
    
        ngx_http_core_create_main_conf,        /* create main configuration */
        ngx_http_core_init_main_conf,          /* init main configuration */
    
        ngx_http_core_create_srv_conf,         /* create server configuration */
        ngx_http_core_merge_srv_conf,          /* merge server configuration */
    
        ngx_http_core_create_loc_conf,         /* create location configuration */
        ngx_http_core_merge_loc_conf           /* merge location configuration */
    };
    
    ngx_module_t  ngx_http_core_module = {
        NGX_MODULE_V1,
        &ngx_http_core_module_ctx,             /* module context */
        ngx_http_core_commands,                /* module directives */
        NGX_HTTP_MODULE,                       /* module type */
        NULL,                                  /* init master */
        NULL,                                  /* init module */
        NULL,                                  /* init process */
        NULL,                                  /* init thread */
        NULL,                                  /* exit thread */
        NULL,                                  /* exit process */
        NULL,                                  /* exit master */
        NGX_MODULE_V1_PADDING
    };

    这是一个NGX_HTTP_MODULE模块,所以ngx_http_core_create_main_conf(),ngx_http_core_create_srv_conf(),ngx_http_core_create_loc_conf()会分别创建三个配置数据结构cmcf, cscf, clcf,并分别存放与ctx->main_conf指针数组,ctx->src_conf指针数组,ctx->loc_conf指针数组当中。

    server配置指令

    server指令由ngx_http_core_module.c文件的ngx_http_core_server()负责解析。
        ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
    
        http_ctx = cf->ctx;   /* cf->ctx指的是http指令对应的ctx */
        ctx->main_conf = http_ctx->main_conf;
    
        ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
    
        ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
    
        for (i = 0; ngx_modules[i]; i++) {
            if (ngx_modules[i]->type != NGX_HTTP_MODULE) {
                continue;
            }
    
            module = ngx_modules[i]->ctx;
    
            if (module->create_srv_conf) {
                mconf = module->create_srv_conf(cf);
                if (mconf == NULL) {
                    return NGX_CONF_ERROR;
                }
    
                ctx->srv_conf[ngx_modules[i]->ctx_index] = mconf;
            }
    
            if (module->create_loc_conf) {
                mconf = module->create_loc_conf(cf);
                if (mconf == NULL) {
                    return NGX_CONF_ERROR;
                }
    
                ctx->loc_conf[ngx_modules[i]->ctx_index] = mconf;
            }
        }
        /* 把这个server指令对应的cscf放到cmcf的servers数组中。 */
        /* cscf的ctx成员包含srv_conf,和loc_conf,指向server层的数据 */
        cscf = ctx->srv_conf[ngx_http_core_module.ctx_index];
        cscf->ctx = ctx;
    
        cmcf = ctx->main_conf[ngx_http_core_module.ctx_index];
    
        cscfp = ngx_array_push(&cmcf->servers);
        if (cscfp == NULL) {
            return NGX_CONF_ERROR;
        }
    
        *cscfp = cscf;

    location配置指令

    location指令由ngx_http_core_module.c文件的ngx_http_core_location()负责解析。
        ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
    
        pctx = cf->ctx;   /* cf->ctx指的是cscf->ctx */
        ctx->main_conf = pctx->main_conf;
        ctx->srv_conf = pctx->srv_conf;
    
        ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
    
        for (i = 0; ngx_modules[i]; i++) {
            if (ngx_modules[i]->type != NGX_HTTP_MODULE) {
                continue;
            }
    
            module = ngx_modules[i]->ctx;
    
            if (module->create_loc_conf) {
                ctx->loc_conf[ngx_modules[i]->ctx_index] =
                                                       module->create_loc_conf(cf);
                if (ctx->loc_conf[ngx_modules[i]->ctx_index] == NULL) {
                     return NGX_CONF_ERROR;
                }
            }
        }
    
        clcf = ctx->loc_conf[ngx_http_core_module.ctx_index];
        clcf->loc_conf = ctx->loc_conf;
        /* cscf->ctx的loc_conf指针数组中,有一个clcf成员,它的locations队列中,存放所有包含的location指令块 */
        pclcf = pctx->loc_conf[ngx_http_core_module.ctx_index];
        ngx_http_add_location(cf, &pclcf->locations, clcf);
    
    

    配置数据结构的总体结构图





    合并配置数据结构

    将http上下文合并到server上下文


    将server上下文合并到location上下文

     
    0
    0
  • 相关阅读:
    BZOJ 2038 小Z的袜子 莫队算法
    POJ 3407 球面距离
    POJ 1375 圆的切线
    BZOJ 1502 月下柠檬树 simpson积分
    UVA 11704
    POJ 1981 定长圆覆盖最多点
    HDU 3982 半平面交+圆和凸多边形面积并
    ZOJ 1104 二分
    使用Singleton来实现Flash和Flex的通信。
    校内API相关
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3093685.html
Copyright © 2020-2023  润新知