整個設定解析主要是函數ngx_init_cycle(&init_cycle)進行處理。
ngx_init_cycle(&init_cycle)
ngx_time_update()//時間更新,也是在main 上講過
rrr
pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE,log) ;//分配一塊16k的記憶體池,第一個節點大約是16k,如果新增小塊記憶體節點,那麼該節點最大為4095
/* * 通过加锁和解锁,来更新如下时间 ngx_cached_time = tp; ngx_cached_http_time.data = p0; ngx_cached_err_log_time.data = p1; ngx_cached_http_log_time.data = p2; ngx_cached_http_log_iso8601.data = p3; */
首先建立核心模組的上下文結構,保存在cycle->conf_ctx對應的結構裡面
核心模組如下:
cycle->pool = pool; cycle->log = log; cycle->new_log.log_level = NGX_LOG_ERR; cycle->conf_prefix; //设置配置文件dir cycle->prefix; //设置运行环境dir cycle->conf_file; //设置配置文件绝对路径 cycle->conf_param; //保存参数 cycle->pathes; //路径数组 cycle->open_files; //分配打开的文件描述符,其中这个结构是一 个链表,每个链表节点都有一个n个size的 cycle->shared_memory; //分配n个共享内存节点,这个是一个list, 每个节点都存在n个ngx_shm_zone_t结构,通过next指向链表后面的节点。 cycle->listening; //listening数组 cycle->conf_ctx = ngx_pcalloc(pool, ngx_max_module*sizeof(void*));
NGX_CORE_MODULE index Ngx_core_module 0 Ngx_errlog_module 1 Ngx_reg_module 6 Ngx_events_module 3 Ngx_http_module 7
nginx先建立NGX_CORE_MODULE是為了創建後面的模組上下文做鋪墊,也就是
NGX_CORE_MODULE是其他模組的基礎,如下:
其中Ngx_errlog_,mx_ ,是根據使用者的conf實際動態的進行創建。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; } }
為conf建立參數,用於保存設定檔的使用者設定key和value,同時建立temp_pool內
存池,conf->ctx指向cycle->conf_ctx,儲存cycle、pool、log,設定模組類型和指令類型,
開始解析主設定檔變數。
解析設定檔的過程主要是ngx_conf_parse進行間接遞歸調用,主要分為main作用域 、event作用域、http作用域、server作用域、location作用域,然後接下來就進行分析。
在解析過程中,對設定檔(nginx.conf)分為三類:
conf.args = ngx_array_create(pool, 10, sizeof(ngx_str_t)); if (conf.args == NULL) { ngx_destroy_pool(pool); return NULL; } conf.temp_pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, log); if (conf.temp_pool == NULL) { ngx_destroy_pool(pool); return NULL; } conf.ctx = cycle->conf_ctx; conf.cycle = cycle; conf.pool = pool; conf.log = log; conf.module_type = NGX_CORE_MODULE; conf.cmd_type = NGX_MAIN_CONF;
進入ngx_conf_parse函數,依照是否為解析檔案、解析區塊、解析參數,來設定不同的值,然後進入ngken_conf_read_token ,這個函數,主要是讀取文件,然後設定一些旗變量,保存用戶配置到conf->args裡面,其中在解析配置文件(nginx.conf)的時候使用一個buffer內存,主要讀取文件,然後解析buffer,解析過程是流式,如果buffer後面還有未解析完,但是沒有遇到分號or大括號之類的,就會把未解析完移動到buffer的頭部,然後在繼續讀文件,進行解析,每呼叫玩一次ngx_conf_read_token就會解析完一個指令,如果設定檔配置有問題,就會報錯。解析完一個使用者的設定後,儲存在conf->args陣列中。如果發現cf->handler有值,就呼叫cf->handler進行回呼處理(一般處理mine.types檔),如果cf->handler為空,那麼就呼叫ngx_conf_handler,遍歷每一個模組的cmd,來case,找到該指令,並且呼叫指令的set回調方法,如果cmd是一個key value的變數設定,給對應模組變數設定完後,就呼叫ngx_conf_read_token,如果是一個區塊的key,例如http、event、location,他們的回呼函數(cmd->set)首先是建立上下文結構變數,然後間接遞歸ngx_conf_parse,當然就會設定不同的上下文。