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

来源:互联网 发布:linux替换命令 编辑:程序博客网 时间:2024/05/20 11:50

配置数据结构的创建过程

初始化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上下文

原创粉丝点击