1. 程式人生 > >Nginx 配置初始化過程

Nginx 配置初始化過程

nginx解析配置檔案,將解析出來得配置存放在ngx_cycle_sconf_ctx中,conf_ctx是個四級指標,因為儲存這些配置需要context,而這些context是有層級關係,最終的配置結構如圖:

http模組的配置有些複雜,由於server的配置還可以出現在http模組中,同時location的配置可以出現在http模組或者server模組中,所以對於http來說也就是最上面的那個ngx_http_ctx_conf_tsrv_confloc_conf是十分有必要的,這兩個指標後面的結構體陣列儲存了在http中的那些server的和location的配置。同樣對於每個server

來說,不需要單獨的main配置了,直接引用main的就可以。每個server必須有自己單獨的ngx_http_core_srv_conf_t,來儲存當前server塊內的配置,這個配置最後會和http的裡面的ngx_http_core_srv_conf_tmerge,這個merge是把父server的配置merge到子server配置上面。對於location的配置,在httpserver中都可以配置,那麼merge的操作需要首先把httplocation配置merge到每個server配置中,然後每個serverlocation配置再和每個location模組中的配置進行merge,這裡
location配置需要merge兩次。舉例ngx_http_core_module模組merge的過程:

    merge過程是按照module一個一個modulemerge,第一步從main配置裡面的servers,遍歷每個server,把main裡面的server配置merge到每個server的配置中,然後把main裡面的location配置merge到每個serverlocation的配置中。第二步再次遍歷每個serverlocations,把這個serverlocation的配置merge到具體的每個location中。

程式碼:


  1. static char *

  2. ngx_http_merge_servers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
  3.     ngx_http_module_t *module, ngx_uint_t ctx_index) //cmcf代表http的main配置
  4. { 
  5.     char *rv; 
  6.     ngx_uint_t s; 
  7.     ngx_http_conf_ctx_t *ctx, saved;
  8.     ngx_http_core_loc_conf_t *clcf;
  9.     ngx_http_core_srv_conf_t **cscfp;
  10.     cscfp = cmcf->servers.elts;             //得到servers陣列,cmcf是main層的配置
  11.     ctx = (ngx_http_conf_ctx_t *) cf->ctx; //ctx是main的 ngx_http_conf_ctx_t
  12.     saved = *ctx;
  13.     rv = NGX_CONF_OK;
  14.     for (= 0; s < cmcf->servers.nelts; s++) { //遍歷每個server,把main的配置merge到每個server中
  15.         /* merge the server{}s' srv_conf'*/
  16.         ctx->srv_conf = cscfp[s]->ctx->srv_conf; 
  17.         if (module->merge_srv_conf) {           //呼叫模組的merge server操作
  18.     //save.srv_conf是父server配置,cscf->ctx->srv_conf是當前server的配置,相當於圖中的第一步
  19.             rv = module->merge_srv_conf(cf, saved.srv_conf[ctx_index],
  20.                                         cscfp[s]->ctx->srv_conf[ctx_index]); 
  21.             if (rv != NGX_CONF_OK) {
  22.                 goto failed;
  23.             } 
  24.         } 
  25. //呼叫模組的merge location操作,把父location配置merge到每個server的location配置相當於圖中的第一步
  26.         if (module->merge_loc_conf) {
  27.             /* merge the server{}'s loc_conf */
  28.             ctx->loc_conf = cscfp[s]->ctx->loc_conf;
  29.             rv = module->merge_loc_conf(cf, saved.loc_conf[ctx_index],
  30.                                         cscfp[s]->ctx->loc_conf[ctx_index]);
  31.             if (rv != NGX_CONF_OK) {
  32.                 goto failed;
  33.             } 
  34.             /* merge the locations{}' loc_conf'*/
  35.             clcf = cscfp[s]->ctx->loc_conf[ngx_http_core_module.ctx_index];
  36. //該merge每個server的location配置到每個location的配置中了,相當於圖中的第二步
  37.             rv = ngx_http_merge_locations(cf, clcf->locations,
  38.                                           cscfp[s]->ctx->loc_conf,
  39.                                           module, ctx_index); 
  40.             if (rv != NGX_CONF_OK) {
  41.                 goto failed;
  42.             }
  43.         }
  44.     }

    serverlocationlocationmerge過程

  1. static char *
  2. ngx_http_merge_locations(ngx_conf_t *cf, ngx_queue_t *locations,
  3.     void **loc_conf, ngx_http_module_t *module, ngx_uint_t ctx_index)
  4. {
  5.     char *rv;
  6.     ngx_queue_t *q;
  7.     ngx_http_conf_ctx_t *ctx, saved;
  8.     ngx_http_core_loc_conf_t *clcf;
  9.     ngx_http_location_queue_t *lq;
  10.     if (locations == NULL) {
  11.         return NGX_CONF_OK;
  12.     }
  13.     ctx = (ngx_http_conf_ctx_t *) cf->ctx;
  14.     saved = *ctx;
  15.     for (= ngx_queue_head(locations);      //遍歷server中的locations佇列
  16.          q != ngx_queue_sentinel(locations);
  17.          q = ngx_queue_next(q))
  18.     {
  19.         lq = (ngx_http_location_queue_t *) q;
  20.         clcf = lq->exact ? lq->exact : lq->inclusive; 
  21.         ctx->loc_conf = clcf->loc_conf;
//loc_conf代表server下location配置,clcf->loc_conf代表每個location的配置
  1.         rv = module->merge_loc_conf(cf, loc_conf[ctx_index],
  2.                                     clcf->loc_conf[ctx_index]); 
  3.         if (rv != NGX_CONF_OK) {
  4.             return rv;
  5.         }
  6.         rv = ngx_http_merge_locations(cf, clcf->locations, clcf->loc_conf,
  7.                                       module, ctx_index);        //遞迴巢狀location
  8.         if (rv != NGX_CONF_OK) {
  9.             return rv;
  10.         }
  11.     }