nginx配置的內存佈局

nginx的配置系統很靈活,不但支持模塊自定義配置項,而且支持多級配置以及合併多級配置項。這樣的設計使得nginx的配置在內存中的佈局也是分成多級的,比較複雜。因此,這裏採用一種自頂向下的方式進行逐級剖析。

這裏需要先說明一下nginx指令的上下文環境以及有效上下文環境。nginx配置的上下文環境指的是指令在配置文件中的位置,比如配置文件全局,http塊全局,http server塊, mail塊全局等。而nginx指令的有效上下文環境指的是指令在nginx配置文件中允許出現的位置。任何出現在其非有效上下文環境中的指令都會被nginx視爲錯誤。

下面來看一段代碼

struct ngx_cycle_s {
    void                  ****conf_ctx;
    ...
};
ngx_cycle_s結構體的conf_ctx字段是nginx配置項的最頂層入口,它是一個四級指針。那麼,該怎麼去理解這個conf_ctx呢?

下面的代碼片段是從ngx_init_cycle函數中提取出來的,我們分析一下它的邏輯:

cycle->conf_ctx = ngx_pcalloc(pool, ngx_max_module * sizeof(void *));//ngx_max_module是當前配置下nginx允許的最大模塊數
...
for (i = 0; cycle->modules[i]; i++) {
        if (cycle->modules[i]->type != NGX_CORE_MODULE) {
            continue;
        }

        module = cycle->modules[i]->ctx;

        if (module->create_conf) {
            rv = module->create_conf(cycle);
            if (rv == NULL) {
                ngx_destroy_pool(pool);
                return NULL;
            }
            cycle->conf_ctx[cycle->modules[i]->index] = rv;
        }
}
可以看出,conf_ctx本身是一個數組,數組大小與當前配置下nginx允許的最大模塊數一致。另外,這裏還調用了類型爲NGX_CORE_MODULE的模塊ctx成員的create_conf回調函數,並且把返回值保存在模塊在conf_ctx中對應的元素中。而這個create_conf回調函數是NGX_CORE_MODULE類型的模塊實現配置環境創建的,也就是說,NGX_CORE_MODULE類型的模塊的配置是保存在conf_ctx與其位置對應的元素中的。那麼,哪些模塊是NGX_CORE_MODULE呢?下表列出了到nginx-1.12.1爲止的NGX_CORE_MODULE以及它們的源碼文件和create_conf返回的實際類型:

ngx_core_module nginx.c ngx_core_conf_t *
ngx_events_module ngx_event.c void ***
ngx_openssl_module ngx_event_openssl.c ngx_openssl_conf_t *
ngx_google_perftools_module ngx_google_perftools_module.c ngx_google_perftools_conf_t *
ngx_http_module ngx_http.c ngx_http_conf_ctx_t *
ngx_errlog_module ngx_log.c NULL
ngx_mail_module ngx_mail.c ngx_mail_conf_ctx_t *
ngx_regex_module ngx_regex.c ngx_regex_conf_t *
ngx_stream_module ngx_stream.c ngx_stream_conf_ctx_t *
ngx_thread_pool_module ngx_thread_pool.c ngx_thread_pool_conf_t *
前面說到,conf_ctx是void ****類型,那麼這些NGX_CORE_MODULE類型的create_conf回調的返回值應該是void ***類型。從上面的表中可以看出,實際上只有ngx_events_module返回了void ***類型,其它的模塊基本上都是各自模塊定義的上下文環境指針,甚至是NULL。也就是說,conf_ctx的元素保存的實際數據是什麼,是由該元素對應的模塊類型決定的。

那麼NGX_CORE_MODULE中的指令的有效上下文環境是什麼呢?很容易可以想到,就是配置文件全局。也就是說,任何在NGX_CORE_MODULE類型的模塊中定義的指令只能出現在配置文件最外層,不能出現在其它任何 位置。

到這裏我們已經可以知道,出現在最外層的配置都會被直接保存在conf_ctx對應的元素指向的內存塊中。下面是從conf_ctx的角度上看,各主要NGX_CORE_MODULE類型模塊的內存佈局圖:


那麼,非全局的配置會被保存在哪裏呢?這與模塊類型相關,不同類型的模塊的配置內存佈局各不相同,會在別的文章中單獨分析。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章