nginx原始碼分析--配置資訊的繼承&合併
這裡只講述http{}模組下的配置:
在ngx_http_block()函式內(這個函式別調用時在ngx_inti_cycle內的ngx_conf_parse函式,這個函式遇到http命令時 回撥ngx_http_block,開啟http{}配置塊的解讀工作),針對每一個http模組,呼叫init_conf之後,有呼叫了ngx_http_merge_servers()。這是為何!
首先明確幾點:一個http{}配置塊內可以包含多個server{}配置塊,每個server{}配置塊可以包含多個location{}配置塊,每個location{}配置塊可以巢狀location{}配置塊。把每個使用{}包含起來的配置塊稱為一個層次。在ngx_http_block中呼叫ngx_conf_parse時,還呼叫了ngx_http_core_server和ngx_http_core_location 這兩個函式是解析server{}塊和location{]塊的。在不同的層次為同一個http模組建立了儲存配置的結構體空間,比如在http{}層次為某一個http模組建立了 main_conf、srv_conf、loc_conf配置,在ngx_http_core_server內為同一個http模組建立了srv_conf loc_conf配置,在ngx_http_core_location函式內為同一個http模組建立了loc_conf配置。但是這是不同層次上的配置。對於某一個http模組中的某一個命令來說,它可能出現的區域有http{} server{} locaton{},如果在某一個server{}塊內沒有這個命令 那麼它就需要從http{}中繼承這個命令,如果某個server{}中存在這個命令,那麼就不需要從http{}中繼承;如果server{}中的某一個location{}中沒有這個命令,那麼就需要從上層(server{}層或者location{}層)繼承,如果上層沒有,直接從http{}中繼承,或者使用預設。整個繼承的流程如上所述。對於某一個http模組中的命令可以出現的層次是它本身自己知道的,怎麼合併(使用函式merge_srv_conf和
merge_loc_conf函式回撥)也是模組本身定義的。正是模組中命令可以出現在不同區域才造成了繼承合併的操作,這也是為了配置檔案的靈活。
解析流程:在ngx_http_block函式中。一個for迴圈為每一個http模組呼叫init_main回撥和ngx_http_merge_servers.
在ngx_http_merge_servers中一個for迴圈 需要遍歷所有的server{}配置塊,首先回調呼叫merge_srv_conf,從http上下文繼承srv_conf配置,然後回撥呼叫merge_loc_conf,從http上下文繼承loc_conf配置,然後處理這個server{}塊下的所有location{}塊 呼叫ngx_http_merge_location
在ngx_http_merge_location中,首先從上文(server{]或者location{})繼承loc_conf配置 然後處理location{]模組下的所有loction{}