Nginx原始碼分析 Nginx配置檔案解析(一)

2021-09-13 04:10:48 字數 3136 閱讀 7021

運營研發團隊 李樂

配置檔案是nginx的基礎,對於學習nginx原始碼甚至開發nginx模組的同學來說更是必須深究。本文將從原始碼從此深入分析nginx配置檔案的解析,配置儲存,與配置查詢。

//獲取限流相關配置

//獲取fastcgi相關配置

為什麼可以這樣獲取到限流和fastcgi相關的配置呢?

相信學習本文之後,這兩個問題將不在話下。

在學習nginx配置檔案的解析過程之前,需要先了解一下nginx模組與指令的一些基本知識。

nginx的配置指令可以分為兩大類:指令塊(如events、http、server和location)與單條指令(如worker_processes、root、rewrite等)。

nginx規定指令塊可以巢狀(如http塊中可以巢狀server指令,server塊中可以巢狀location指令),指令可以同時出現在不同的指令塊(如root指令可以同時出現在http、server和location指令塊)。

配置檔案這種層次的複雜性,導致配置檔案的解析與儲存等的複雜性。

結構體ngx_module_t用於定義乙個nginx模組,這裡需要重點關注以下幾個字段。

struct ngx_module_s 

ctx_index用於給同型別的模組編號,比如:

}

nginx的各個模組組合形成了其強大的處理能力,而每個模組只實現乙個特定的功能。比如限流功能由模組ngx_http_limit_conn_module或者模組實現ngx_http_limit_req_module;fastcgi**功能由模組ngx_http_fastcgi_module

實現;proxy**功能由ngx_http_proxy_module(當然**功能的實現還必須有模組ngx_http_upstream_module)。

當我們配置了指令proxy_pass或者fastcgi_pass時,該指令應該由哪個模組來解析呢?顯然應該由實現此功能的模組來解析。即nginx配置檔案的解析是分散到各個模組的。

每個模組都有乙個commands陣列,儲存該模組可以解析的所有配置指令。指令結構體由ngx_command_t定義:

struct ngx_command_s ;
用於校驗引數數目。常用指令型別如下:

下面這張圖展示了指令的基本分類(通過顏色區分,各種顏色的文字描述指令型別以及該指令只能被哪種型別的模組解析):

http配置相對複雜,h指令塊巢狀,模組眾多,導致http配置解析與儲存的複雜性。因此本小節重點講述http相關配置儲存的方案設計。

前面提到每個模組負責解析和儲存自己關心的配置指令,即每個模組都應該有個可以儲存配置的結構體,該結構體通過模組上下文結構體的函式create_conf,create_main_conf,create_srv_conf或者create_loc_conf建立。

比如說如下表:

問題來了,每個模組建立自己的配置結構體,儲存是完全分散的,如何能快速查詢到這些配置結構體呢?

最容易想到的就是宣告乙個void*的陣列,陣列元素數目就是模組數目,以模組的index欄位作為陣列的索引,陣列的每個元素都指向對應模組的配置結構體。

但是不要忘記,nginx配置檔案是有層次結構的,如http指令塊中可以宣告多個單條指令和多個server指令塊,server指令塊中可以宣告多個單條指令和多個location指令塊,location配置又可以宣告多個單條指令。

我們可以這樣來設計:

http指令塊內包含的所有指令或者指令塊只能被http模組(ngx_http_module)解析。

這個結構似乎是可以的,但是我們忘記了一件事:一些指令可以同時出現在http指令塊、server指令塊和location指令塊。

即http塊中的指令型別可以是ngx_http_main_conf,也可以是ngx_http_main_conf|ngx_http_srv_conf,還可以是ngx_http_main_conf|ngx_http_srv_confngx_http_loc_conf;

而server塊中的指令型別可以是ngx_http_srv_conf,也可以是ngx_http_srv_confngx_http_loc_conf。(位或運算表示同時屬於多種型別)

比如說指令root的型別位ngx_http_main_conf|ngx_http_srv_conf|ngx_http_loc_conf,此時該配置應該儲存在loc_conf配置結構,但是其可能會配置在http指令塊中、server指令塊或者location指令塊。

為此我們修改上面的結構如下:

上面我們分析了http指令塊內部的所有指令可能的儲存格式,events指令塊內部儲存格式相比較簡單很多,讀者可以試著畫一畫。

那麼這是否是nginx採用的儲存格式呢?可以說和上圖非常類似,nginx設計的配置儲存格式見下圖,這裡暫時留兩個疑問:

本文作為nginx配置檔案解析的第一小篇,簡要介紹了nginx模組和指令的基本概念,同時針對http相關配置的儲存格式進行了初步設計與講解,為下文《nginx配置檔案解析(二)》講解。配置檔案解析原始碼分析打下基礎。

nginx原始碼分析 從原始碼看nginx框架總結

nginx原始碼總結 1 中沒有特別繞特別彆扭的編碼實現,從變數的定義呼叫函式的實現封裝,都非常恰當,比如從函式命名或者變數命名就可以看出來定義的大體意義,函式的基本功能,再好的架構實現在編碼習慣差的人實現也會黯然失色,如果透徹理解 的實現,領悟架構的設計初衷,覺得每塊 就想經過耐心雕琢一樣,不僅僅...

nginx 原始碼分析

近期準備研究一下nginx原始碼,此處記錄一下。計畫 1 了解evan miller 的文章 2 了解nginx的組織架構 3 了解nginx的基本資料結構 4 熟悉nginx的主要module及執行機制,主要是core http event os 5 簡單的module開發及測試 一 準備 為了方...

Nginx原始碼分析 nginx的配置

nginx原始碼分析 nginx的配置 nginx都是乙個master程序來管理多個worker程序。worker程序的數量與伺服器上的cpu核心數相等。master是管理worker,接受外部訊號,worker程序之間通過共享記憶體 原子操作實現通訊和同步。任意乙個worker程序出現錯誤從而導致...