[nginx源码分析]配置合并

整个ngx_http_block中的ngx_conf_parse配置解析完成,,后面主要对配置文件进行优化。

优化可以分为以下:

1 配置作用域合并

2location划分

3 http header回调初始化hash

4 初始化http收包回调函数

5 server中的server_name形成hash


本篇主要说配置合并的事情

配置作用域合并

主要是http、server、location,http作用域最大、server其次、location最精细化。合并的主要流程是,同一个模块中的上下文变量可以存在在不同的作用域,可以在配置文件中的http作用域,也可以在server作用域,还可以写在location作用域,如果该变量在server作用域没有设置,但是http作用域配置文件中设置了该值,那么server作用域的该值,就会被http作用域的合并掉,使用http作用的值,同理location和server合并。那么下面来看核心代码。

cmcf = ctx->main_conf[ngx_http_core_module.ctx_index];                          //获取http中的main_conf[ngx_http_core_module.ctx_index] 中的信息,包括server信息
      cscfp = cmcf->servers.elts;
  
      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;
  
          /* init http{} main_conf's */
  
          if (module->init_main_conf) {                                               //调用每个http module的init_main_conf函数,来初始化那些用户没设置的值
              rv = module->init_main_conf(cf, ctx->main_conf[mi]);
              if (rv != NGX_CONF_OK) {
                  goto failed;
              }
          }
  
          rv = ngx_http_merge_servers(cf, cmcf, module, mi);                                                                                                                                                                             
          if (rv != NGX_CONF_OK) {
              goto failed;
          }
      }

主要是获取server上下文cscfp,遍历NGX_HTTP_MODULE调用模块的init_main_conf函数,进行初始化和ngx_http_merge_servers进行作用域合并。我们就列举最核心的模块ngx_http_core_module的init_main_conf和ngx_http_merge_servers,分析完ngx_http_core_module的这两个函数,你就会清楚作用域合并原理。

ngx_http_core_module的init_main_conf回调函数为ngx_http_core_init_main_conf函数,

static char *
 ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf)                                                                                                                                                                               
 {
     ngx_http_core_main_conf_t *cmcf = conf;
 	 //如果未设置,给一个默认值
     if (cmcf->server_names_hash_max_size == NGX_CONF_UNSET_UINT) {
         cmcf->server_names_hash_max_size = 512;
     }
 	 //如果未设置,给一个默认值
     if (cmcf->server_names_hash_bucket_size == NGX_CONF_UNSET_UINT) {
         cmcf->server_names_hash_bucket_size = ngx_cacheline_size;
     }
 	 //.如果未设置,那么给一个默认值
     cmcf->server_names_hash_bucket_size =
             ngx_align(cmcf->server_names_hash_bucket_size, ngx_cacheline_size);
     if (cmcf->variables_hash_max_size == NGX_CONF_UNSET_UINT) {
         cmcf->variables_hash_max_size = 512;
     }
 
     if (cmcf->variables_hash_bucket_size == NGX_CONF_UNSET_UINT) {
         cmcf->variables_hash_bucket_size = 64;
     }
 
     cmcf->variables_hash_bucket_size =
                ngx_align(cmcf->variables_hash_bucket_size, ngx_cacheline_size);
 
     if (cmcf->ncaptures) {
         cmcf->ncaptures = (cmcf->ncaptures + 1) * 3;
     }
 
     return NGX_CONF_OK;
 }

从上面函数可以看到,如果用户没有在配置文件设置该模块main作用域(即http作用域)相应的值,那么就给他们赋值一个默认值。

作用域合并函数:

cf是http上下文

cmcf是ngx_http_core_module在main的上下文(即http上下文)

module是遍历的模块(ngx_modules)

mi 是该模块在http上下文的索引,对应的是ngx_module[m]

ngx_http_merge_servers(cf,cmcf, module, mi)

核心代码:

 for (s = 0; s < cmcf->servers.nelts; s++) {
  
          /* merge the server{}s' srv_conf's */
  
          ctx->srv_conf = cscfp[s]->ctx->srv_conf;
  
          if (module->merge_srv_conf) {
              rv = module->merge_srv_conf(cf, saved.srv_conf[ctx_index], /*http的srv_conf*/
             cscfp[s]->ctx->srv_conf[ctx_index]);//server的srv_conf进行合并
              if (rv != NGX_CONF_OK) {
                  goto failed;
              }
          }
  
          if (module->merge_loc_conf) {
  
              /* merge the server{}'s loc_conf */
  
              ctx->loc_conf = cscfp[s]->ctx->loc_conf;
  
              rv = module->merge_loc_conf(cf, saved.loc_conf[ctx_index],
                                          cscfp[s]->ctx->loc_conf[ctx_index]);
              if (rv != NGX_CONF_OK) {
                  goto failed;
              }
  
              /* merge the locations{}' loc_conf's */
  
              clcf = cscfp[s]->ctx->loc_conf[ngx_http_core_module.ctx_index];
  
              rv = ngx_http_merge_locations(cf, clcf->locations,
                                            cscfp[s]->ctx->loc_conf,
                                            module, ctx_index);
              if (rv != NGX_CONF_OK) {
                  goto failed;
              }
          }                                                                                                                                                                                                                              
      }

ngx_http_merge_servers调用者(外层函数)是对模块(ngx_modules)进行遍历,也就是说对每一个模块的每一个server都会进行处理。然后我们聚焦于ngx_http_merge_servers函数,主要是对于一个模块合并该模块的http、server、location不同上下文的变量,http->server->location会越来越精准化,就像是c++的作用域一样,http可以看作是http作用域,server可以看作是server作用域,location相当于块作用域,内层作用域可以隐藏到外层作用域和这里的合并是一个道理。

ngx_http_merge_servers核心的两个函数是merge_srv_conf和merge_loc_conf,merge_srv_conf主要合并http和server server上下文,merge_loc_conf主要合并http和server的loc上下文, ngx_http_merge_locations主要合并server和loc的loc上下文,同时该函数还进行location的递归调用,用于合并location中的location。





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值