Nginx 配置初始化過程
阿新 • • 發佈:2019-01-04
nginx解析配置檔案,將解析出來得配置存放在ngx_cycle_s的conf_ctx中,conf_ctx是個四級指標,因為儲存這些配置需要context,而這些context是有層級關係,最終的配置結構如圖:
http模組的配置有些複雜,由於server的配置還可以出現在http模組中,同時location的配置可以出現在http模組或者server模組中,所以對於http來說也就是最上面的那個ngx_http_ctx_conf_t有srv_conf和loc_conf是十分有必要的,這兩個指標後面的結構體陣列儲存了在http中的那些server的和location的配置。同樣對於每個server
merge過程是按照module一個一個module的merge,第一步從main配置裡面的servers,遍歷每個server,把main裡面的server配置merge到每個server的配置中,然後把main裡面的location配置merge到每個server的location的配置中。第二步再次遍歷每個server的locations,把這個server的location的配置merge到具體的每個location中。
程式碼:
-
static char *
-
ngx_http_merge_servers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
-
ngx_http_module_t *module, ngx_uint_t ctx_index) //cmcf代表http的main配置
-
{
-
char *rv;
-
ngx_uint_t s;
-
ngx_http_conf_ctx_t *ctx, saved;
-
ngx_http_core_loc_conf_t *clcf;
-
ngx_http_core_srv_conf_t **cscfp;
-
cscfp = cmcf->servers.elts;
//得到servers陣列,cmcf是main層的配置
-
ctx = (ngx_http_conf_ctx_t *) cf->ctx; //ctx是main的
ngx_http_conf_ctx_t
-
saved = *ctx;
-
rv = NGX_CONF_OK;
-
for (s = 0; s < cmcf->servers.nelts; s++) { //遍歷每個server,把main的配置merge到每個server中
-
/* merge the server{}s' srv_conf's */
-
ctx->srv_conf = cscfp[s]->ctx->srv_conf;
-
if (module->merge_srv_conf) {
//呼叫模組的merge server操作
-
//save.srv_conf是父server配置,cscf->ctx->srv_conf是當前server的配置,相當於圖中的第一步
-
rv = module->merge_srv_conf(cf, saved.srv_conf[ctx_index],
- cscfp[s]->ctx->srv_conf[ctx_index]);
-
if (rv != NGX_CONF_OK) {
-
goto failed;
-
}
-
}
-
//呼叫模組的merge
location操作,把父location配置merge到每個server的location配置相當於圖中的第一步
-
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];
- //該merge每個server的location配置到每個location的配置中了,相當於圖中的第二步
-
rv = ngx_http_merge_locations(cf, clcf->locations,
-
cscfp[s]->ctx->loc_conf,
- module, ctx_index);
-
if (rv != NGX_CONF_OK) {
-
goto failed;
-
}
-
}
- }
server中location和location的merge過程
-
static char *
-
ngx_http_merge_locations(ngx_conf_t *cf, ngx_queue_t *locations,
-
void **loc_conf, ngx_http_module_t *module, ngx_uint_t
ctx_index)
-
{
-
char *rv;
-
ngx_queue_t *q;
-
ngx_http_conf_ctx_t *ctx, saved;
-
ngx_http_core_loc_conf_t *clcf;
-
ngx_http_location_queue_t *lq;
-
if (locations == NULL) {
-
return NGX_CONF_OK;
-
}
-
ctx = (ngx_http_conf_ctx_t *) cf->ctx;
-
saved = *ctx;
-
for (q = ngx_queue_head(locations);
//遍歷server中的locations佇列
-
q != ngx_queue_sentinel(locations);
-
q = ngx_queue_next(q))
-
{
-
lq = (ngx_http_location_queue_t *) q;
-
clcf = lq->exact ? lq->exact : lq->inclusive;
-
ctx->loc_conf = clcf->loc_conf;
-
rv = module->merge_loc_conf(cf, loc_conf[ctx_index],
-
clcf->loc_conf[ctx_index]);
-
if (rv != NGX_CONF_OK) {
-
return rv;
-
}
-
rv = ngx_http_merge_locations(cf, clcf->locations, clcf->loc_conf,
-
module, ctx_index); //遞迴巢狀location
-
if (rv != NGX_CONF_OK) {
-
return rv;
-
}
- }