Nginx:管理HTTP模塊的配置項


參考資料<深入理解Nginx>

 

一個nginx.conf的例子

http {
    mytest_num 1;
    server {
        server_name A;
        listen 80;
        mytest_num 2;
        location /L1 {
            mytest_num 3;
        }
        location /L2 {
            mytest_num 4;
        }
    }  
    server {
        server_name B;
        listen 80;
        location /R1 {
            mytest_num 5;
        }
        location /R2 {
            mytest_num 6;
        }
    }
}

 

 

核心結構體ngx_http_conf_ctx_t

typedef struct {
    //指向一個指針數組,數組中的每個成員都是由所有HTTP模塊的create_main_conf方法創建的存放全局配置項的結構體
    void **main_conf;
    //指向一個指針數組,數組中的每個成員都是由所有HTTP模塊的create_srv_conf方法創建的存放與server相關的結構體
    void **srv_conf;
    //指向一個指針數組,數組中的每個成員都是由所有HTTP模塊的create_loc_conf方法創建的存放與location相關的結構體
    void **loc_conf;
} ngx_http_conf_ctx_t;

 

 

管理main級別下的配置項

在處理http{}塊內的main級別配置項時,對每個HTTP模塊,都會調用create_main_conf、create_srv_conf、create_loc_conf方法建立3個結構體。

它們將以下面所示的數據結構保存起來

 

 

管理server級別下的配置項

在解析main級別配置項時,如果發現了server{}配置項,就會回調ngx_http_core_server方法解析srv級別的配置項。

在處理server{}塊內的srv級別配置項時,對於每個HTTP模塊,都會調用create_srv_conf、create_loc_conf方法建立兩個結構體

(其main_conf指針指向所屬的http塊下ngx_http_conf_ctx_t結構體的main_conf指針數組)。

那么HTTP框架是如何管理srv級別的配置項的呢?事實上,在解析main級別的配置項時ngx_http_core_module模塊的create_main_conf方法創建了一個很重要的結構體ngx_http_core_main_conf_t:

typedef struct {
    //存儲指針的動態數組,每個指針指向ngx_http_core_srv_conf_t結構體的地址,用於管理srv級別的配置項
    ngx_array_t servers;
    ...
} ngx_http_core_main_conf_t;

而在解析srv級別配置項時,ngx_http_core_module模塊會調用create_srv_conf方法創建一個ngx_http_core_srv_conf_t結構體:

typedef struct {
    //指向當前server塊所屬的ngx_http_conf_ctx_t結構體
    ngx_http_conf_ctx_t *ctx;
    //當前server塊的虛擬主機名
    ngx_str_t server_name;
    ...
} ngx_http_core_srv_conf_t;

它們的關系如下圖所示

 

 

管理location級別下的配置項

在解析srv級別配置項時,如果發現了location{}配置項,就會回調ngx_http_core_location方法來解析loc級別的配置項

在處理location{}塊內的loc級別的配置項時,對於每個HTTP模塊,都會調用create_loc_conf方法來建立一個結構體

(其main_conf和srv_conf指針都指向所屬的server塊下ngx_http_conf_ctx_t結構體的main_conf和srv_conf指針數組)。

那么location級別的配置項時如何管理起來的呢?首先在解析loc級別的配置項時,ngx_http_core_module模塊會在create_loc_conf方法中生成ngx_http_core_loc_conf_t結構體:

struct ngx_http_core_loc_conf_s {
    //location的名稱,即nginx.conf中location后的表達式
    ngx_str_t name;
    //指向所屬location塊內ngx_http_conf_ctx_t結構體中的loc_conf指針數組,它保存着當前location塊內所有HTTP模塊crete_loc_conf方法產生的結構體指針
    void **loc_conf;
    //將同一個server塊內多個表達location塊的ngx_http_core_loc_conf_t結構體以雙向鏈表方式組織起來,該locations指向ngx_http_location_queue_t結構體
    ngx_queue_t *locations;
    ...
};

可以認為該結構體對應着當前解析的location塊,因為它已經擁有足夠的信息來表達一個location塊:它的loc_conf成員可以引用到個HTTP模塊在當前location塊中的配置項

其中ngx_http_location_queue_t結構的定義如下

typedef struct {
    //queue將作為ngx_queue_t雙向鏈表勇氣,從而將ngx_http_location_queue_t結構體連接起來
    ngx_queue_t queue;
    //如果location中的字符串可以景區匹配,exact將指向對應的ngx_http_core_loc_conf_t結構體
    ngx_http_core_loc_conf_t *exact;
    //如果location中的字符串無法精確匹配,inclusive將指向對應的ngx_http_core_conf_t結構體,否則為NULL
    ngx_http_core_loc_conf_t *inclusive;
    //指向location的名稱
    ngx_str_t *name;
    ...
} ngx_http_location_queue_t;

Nginx將ngx_http_core_loc_conf_t用雙向鏈表組織起來,也就是把location級別的配置項結構體管理起來了。

(其中所屬srv配置塊中ngx_http_core_module模塊在create_loc_conf方法中生成ngx_http_core_loc_conf_t結構體為鏈表的首元素),具體結構如下圖

 

 

合並不同級別的配置項

HTTP框架提供了merge_srv_conf方法用於合並main級別和srv級別的server相關的配置項,

同時,它還提供了merge_loc_conf方法用於合並main級別、srv級別、loc級別的location相關的配置項。

合並不同級別的配置項的步驟如下:

1.遍歷所有HTTP模塊,如果該模塊實現了merge_srv_conf方法,則調用該方法來合並main級別和srv級別的server相關的結構體;

2.遍歷所有HTTP模塊,如果該模塊實現了merge_loc_conf方法,先將main級別和srv級別的location相關的結構體合並,

   然后將srv級別和loc級別的location相關的結構體合並。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM