模塊配置結(jié)構(gòu)
基本上每個(gè)模塊都會(huì)提供一些配置指令,以便于用戶(hù)可以通過(guò)配置來(lái)控制該模塊的行為。那么這些配置信息怎么存儲(chǔ)呢?那就需要定義該模塊的配置結(jié)構(gòu)來(lái)進(jìn)行存儲(chǔ)。
大家都知道 Nginx 的配置信息分成了幾個(gè)作用域(scope,有時(shí)也稱(chēng)作上下文),這就是 main,server 以及 location。同樣的每個(gè)模塊提供的配置指令也可以出現(xiàn)在這幾個(gè)作用域里。那對(duì)于這三個(gè)作用域的配置信息,每個(gè)模塊就需要定義三個(gè)不同的數(shù)據(jù)結(jié)構(gòu)去進(jìn)行存儲(chǔ)。當(dāng)然,不是每個(gè)模塊都會(huì)在這三個(gè)作用域都提供配置指令的。那么也就不一定每個(gè)模塊都需要定義三個(gè)數(shù)據(jù)結(jié)構(gòu)去存儲(chǔ)這些配置信息了。視模塊的實(shí)現(xiàn)而言,需要幾個(gè)就定義幾個(gè)。
有一點(diǎn)需要特別注意的就是,在模塊的開(kāi)發(fā)過(guò)程中,我們最好使用 Nginx 原有的命名習(xí)慣。這樣跟原代碼的契合度更高,看起來(lái)也更舒服。
對(duì)于模塊配置信息的定義,命名習(xí)慣是ngx_http_<module name>_(main|srv|loc)_conf_t。這里有個(gè)例子,就是從我們后面將要展示給大家的 hello module 中截取的。
typedef struct { ngx_str_t hello_string; ngx_int_t hello_counter; }ngx_http_hello_loc_conf_t;
模塊配置指令
一個(gè)模塊的配置指令是定義在一個(gè)靜態(tài)數(shù)組中的。同樣地,我們來(lái)看一下從 hello module 中截取的模塊配置指令的定義。
static ngx_command_t ngx_http_hello_commands[] = { { ngx_string("hello_string"), NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS|NGX_CONF_TAKE1, ngx_http_hello_string, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_hello_loc_conf_t, hello_string), NULL }, { ngx_string("hello_counter"), NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, ngx_http_hello_counter, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_hello_loc_conf_t, hello_counter), NULL }, ngx_null_command };
其實(shí)看這個(gè)定義,就基本能看出來(lái)一些信息。例如,我們是定義了兩個(gè)配置指令,一個(gè)是叫 hello_string,可以接受一個(gè)參數(shù),或者是沒(méi)有參數(shù)。另外一個(gè)命令是 hello_counter,接受一個(gè) NGX_CONF_FLAG 類(lèi)型的參數(shù)。除此之外,似乎看起來(lái)有點(diǎn)迷惑。沒(méi)有關(guān)系,我們來(lái)詳細(xì)看一下 ngx_command_t,一旦我們了解這個(gè)結(jié)構(gòu)的詳細(xì)信息,那么我相信上述這個(gè)定義所表達(dá)的所有信息就不言自明了。
ngx_command_t 的定義,位于src/core/ngx_conf_file.h中。
struct ngx_command_s { ngx_str_t name; ngx_uint_t type; char *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); ngx_uint_t conf; ngx_uint_t offset; void *post; };
name: 配置指令的名稱(chēng)。
type: 該配置的類(lèi)型,其實(shí)更準(zhǔn)確一點(diǎn)說(shuō),是該配置指令屬性的集合。Nginx 提供了很多預(yù)定義的屬性值(一些宏定義),通過(guò)邏輯或運(yùn)算符可組合在一起,形成對(duì)這個(gè)配置指令的詳細(xì)的說(shuō)明。下面列出可在這里使用的預(yù)定義屬性值及說(shuō)明。
- NGX_CONF_NOARGS:配置指令不接受任何參數(shù)。
- NGX_CONF_TAKE1:配置指令接受 1 個(gè)參數(shù)。
- NGX_CONF_TAKE2:配置指令接受 2 個(gè)參數(shù)。
- NGX_CONF_TAKE3:配置指令接受 3 個(gè)參數(shù)。
- NGX_CONF_TAKE4:配置指令接受 4 個(gè)參數(shù)。
- NGX_CONF_TAKE5:配置指令接受 5 個(gè)參數(shù)。
- NGX_CONF_TAKE6:配置指令接受 6 個(gè)參數(shù)。
- NGX_CONF_TAKE7:配置指令接受 7 個(gè)參數(shù)。
可以組合多個(gè)屬性,比如一個(gè)指令即可以不填參數(shù),也可以接受1個(gè)或者2個(gè)參數(shù)。那么就是NGX_CONF_NOARGS|NGX_CONF_TAKE1|NGX_CONF_TAKE2。如果寫(xiě)上面三個(gè)屬性在一起,你覺(jué)得麻煩,那么沒(méi)有關(guān)系,Nginx 提供了一些定義,使用起來(lái)更簡(jiǎn)潔。
- NGX_CONF_TAKE12:配置指令接受 1 個(gè)或者 2 個(gè)參數(shù)。
- NGX_CONF_TAKE13:配置指令接受 1 個(gè)或者 3 個(gè)參數(shù)。
- NGX_CONF_TAKE23:配置指令接受 2 個(gè)或者 3 個(gè)參數(shù)。
- NGX_CONF_TAKE123:配置指令接受 1 個(gè)或者 2 個(gè)或者 3 參數(shù)。
- NGX_CONF_TAKE1234:配置指令接受 1 個(gè)或者 2 個(gè)或者 3 個(gè)或者 4 個(gè)參數(shù)。
- NGX_CONF_1MORE:配置指令接受至少一個(gè)參數(shù)。
- NGX_CONF_2MORE:配置指令接受至少兩個(gè)參數(shù)。
- NGX_CONF_MULTI: 配置指令可以接受多個(gè)參數(shù),即個(gè)數(shù)不定。
- NGX_CONF_BLOCK:配置指令可以接受的值是一個(gè)配置信息塊。也就是一對(duì)大括號(hào)括起來(lái)的內(nèi)容。里面可以再包括很多的配置指令。比如常見(jiàn)的 server 指令就是這個(gè)屬性的。
- NGX_CONF_FLAG:配置指令可以接受的值是"on"或者"off",最終會(huì)被轉(zhuǎn)成 bool 值。
- NGX_CONF_ANY:配置指令可以接受的任意的參數(shù)值。一個(gè)或者多個(gè),或者"on"或者"off",或者是配置塊。
最后要說(shuō)明的是,無(wú)論如何,Nginx 的配置指令的參數(shù)個(gè)數(shù)不可以超過(guò) NGX_CONF_MAX_ARGS 個(gè)。目前這個(gè)值被定義為 8,也就是不能超過(guò) 8 個(gè)參數(shù)值。
下面介紹一組說(shuō)明配置指令可以出現(xiàn)的位置的屬性。
- NGX_DIRECT_CONF:可以出現(xiàn)在配置文件中最外層。例如已經(jīng)提供的配置指令 daemon,master_process 等。
- NGX_MAIN_CONF: http、mail、events、error_log 等。
- NGX_ANY_CONF: 該配置指令可以出現(xiàn)在任意配置級(jí)別上。
對(duì)于我們編寫(xiě)的大多數(shù)模塊而言,都是在處理http相關(guān)的事情,也就是所謂的都是NGX_HTTP_MODULE,對(duì)于這樣類(lèi)型的模塊,其配置可能出現(xiàn)的位置也是分為直接出現(xiàn)在http里面,以及其他位置。
- NGX_HTTP_MAIN_CONF: 可以直接出現(xiàn)在 http 配置指令里。
- NGX_HTTP_SRV_CONF: 可以出現(xiàn)在 http 里面的 server 配置指令里。
- NGX_HTTP_LOC_CONF: 可以出現(xiàn)在 http server 塊里面的 location 配置指令里。
- NGX_HTTP_UPS_CONF: 可以出現(xiàn)在 http 里面的 upstream 配置指令里。
- NGX_HTTP_SIF_CONF: 可以出現(xiàn)在 http 里面的 server 配置指令里的 if 語(yǔ)句所在的 block 中。
- NGX_HTTP_LMT_CONF: 可以出現(xiàn)在 http 里面的 limit_except 指令的 block 中。
- NGX_HTTP_LIF_CONF: 可以出現(xiàn)在 http server 塊里面的 location 配置指令里的 if 語(yǔ)句所在的 block 中。
set: 這是一個(gè)函數(shù)指針,當(dāng) Nginx 在解析配置的時(shí)候,如果遇到這個(gè)配置指令,將會(huì)把讀取到的值傳遞給這個(gè)函數(shù)進(jìn)行分解處理。因?yàn)榫唧w每個(gè)配置指令的值如何處理,只有定義這個(gè)配置指令的人是最清楚的。來(lái)看一下這個(gè)函數(shù)指針要求的函數(shù)原型。
char *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
先看該函數(shù)的返回值,處理成功時(shí),返回 NGX_OK,否則返回 NGX_CONF_ERROR 或者是一個(gè)自定義的錯(cuò)誤信息的字符串。
再看一下這個(gè)函數(shù)被調(diào)用的時(shí)候,傳入的三個(gè)參數(shù)。
- cf: 該參數(shù)里面保存從配置文件讀取到的原始字符串以及相關(guān)的一些信息。特別注意的是這個(gè)參數(shù)的args字段是一個(gè) ngx_str_t類(lèi)型的數(shù)組,該數(shù)組的首個(gè)元素是這個(gè)配置指令本身,第二個(gè)元素是指令的第一個(gè)參數(shù),第三個(gè)元素是第二個(gè)參數(shù),依次類(lèi)推。
- cmd: 這個(gè)配置指令對(duì)應(yīng)的 ngx_command_t 結(jié)構(gòu)。
- conf: 就是定義的存儲(chǔ)這個(gè)配置值的結(jié)構(gòu)體,比如在上面展示的那個(gè) ngx_http_hello_loc_conf_t。當(dāng)解析這個(gè) hello_string 變量的時(shí)候,傳入的 conf 就指向一個(gè) ngx_http_hello_loc_conf_t 類(lèi)型的變量。用戶(hù)在處理的時(shí)候可以使用類(lèi)型轉(zhuǎn)換,轉(zhuǎn)換成自己知道的類(lèi)型,再進(jìn)行字段的賦值。
為了更加方便的實(shí)現(xiàn)對(duì)配置指令參數(shù)的讀取,Nginx 已經(jīng)默認(rèn)提供了對(duì)一些標(biāo)準(zhǔn)類(lèi)型的參數(shù)進(jìn)行讀取的函數(shù),可以直接賦值給 set 字段使用。下面來(lái)看一下這些已經(jīng)實(shí)現(xiàn)的 set 類(lèi)型函數(shù)。
- ngx_conf_set_flag_slot: 讀取 NGX_CONF_FLAG 類(lèi)型的參數(shù)。
- ngx_conf_set_str_slot:讀取字符串類(lèi)型的參數(shù)。
- ngx_conf_set_str_array_slot: 讀取字符串?dāng)?shù)組類(lèi)型的參數(shù)。
- ngx_conf_set_keyval_slot: 讀取鍵值對(duì)類(lèi)型的參數(shù)。
- ngx_conf_set_num_slot: 讀取整數(shù)類(lèi)型(有符號(hào)整數(shù) ngx_int_t)的參數(shù)。
- ngx_conf_set_size_slot:讀取 size_t 類(lèi)型的參數(shù),也就是無(wú)符號(hào)數(shù)。
- ngx_conf_set_off_slot: 讀取 off_t 類(lèi)型的參數(shù)。
- ngx_conf_set_msec_slot: 讀取毫秒值類(lèi)型的參數(shù)。
- ngx_conf_set_sec_slot: 讀取秒值類(lèi)型的參數(shù)。
- ngx_conf_set_bufs_slot: 讀取的參數(shù)值是 2 個(gè),一個(gè)是 buf 的個(gè)數(shù),一個(gè)是 buf 的大小。例如: output_buffers 1 128k;
- ngx_conf_set_enum_slot: 讀取枚舉類(lèi)型的參數(shù),將其轉(zhuǎn)換成整數(shù) ngx_uint_t 類(lèi)型。
- ngx_conf_set_bitmask_slot: 讀取參數(shù)的值,并將這些參數(shù)的值以 bit 位的形式存儲(chǔ)。例如:HttpDavModule 模塊的 dav_methods 指令。
conf: 該字段被 NGX_HTTP_MODULE 類(lèi)型模塊所用 (我們編寫(xiě)的基本上都是 NGX_HTTP_MOUDLE,只有一些 Nginx 核心模塊是非 NGX_HTTP_MODULE),該字段指定當(dāng)前配置項(xiàng)存儲(chǔ)的內(nèi)存位置。實(shí)際上是使用哪個(gè)內(nèi)存池的問(wèn)題。因?yàn)?http 模塊對(duì)所有 http 模塊所要保存的配置信息,劃分了 main, server 和 location 三個(gè)地方進(jìn)行存儲(chǔ),每個(gè)地方都有一個(gè)內(nèi)存池用來(lái)分配存儲(chǔ)這些信息的內(nèi)存。這里可能的值為 NGX_HTTP_MAIN_CONF_OFFSET、NGX_HTTP_SRV_CONF_OFFSET 或 NGX_HTTP_LOC_CONF_OFFSET。當(dāng)然也可以直接置為 0,就是 NGX_HTTP_MAIN_CONF_OFFSET。
offset: 指定該配置項(xiàng)值的精確存放位置,一般指定為某一個(gè)結(jié)構(gòu)體變量的字段偏移。因?yàn)閷?duì)于配置信息的存儲(chǔ),一般我們都是定義個(gè)結(jié)構(gòu)體來(lái)存儲(chǔ)的。那么比如我們定義了一個(gè)結(jié)構(gòu)體 A,該項(xiàng)配置的值需要存儲(chǔ)到該結(jié)構(gòu)體的 b 字段。那么在這里就可以填寫(xiě)為 offsetof(A, b)。對(duì)于有些配置項(xiàng),它的值不需要保存或者是需要保存到更為復(fù)雜的結(jié)構(gòu)中時(shí),這里可以設(shè)置為 0。
post: 該字段存儲(chǔ)一個(gè)指針。可以指向任何一個(gè)在讀取配置過(guò)程中需要的數(shù)據(jù),以便于進(jìn)行配置讀取的處理。大多數(shù)時(shí)候,都不需要,所以簡(jiǎn)單地設(shè)為 0 即可。
看到這里,應(yīng)該就比較清楚了。ngx_http_hello_commands 這個(gè)數(shù)組每 5 個(gè)元素為一組,用來(lái)描述一個(gè)配置項(xiàng)的所有情況。那么如果有多個(gè)配置項(xiàng),只要按照需要再增加 5 個(gè)對(duì)應(yīng)的元素對(duì)新的配置項(xiàng)進(jìn)行說(shuō)明。
需要注意的是,就是在ngx_http_hello_commands這個(gè)數(shù)組定義的最后,都要加一個(gè)ngx_null_command作為結(jié)尾。
模塊上下文結(jié)構(gòu)
這是一個(gè) ngx_http_module_t 類(lèi)型的靜態(tài)變量。這個(gè)變量實(shí)際上是提供一組回調(diào)函數(shù)指針,這些函數(shù)有在創(chuàng)建存儲(chǔ)配置信息的對(duì)象的函數(shù),也有在創(chuàng)建前和創(chuàng)建后會(huì)調(diào)用的函數(shù)。這些函數(shù)都將被 Nginx 在合適的時(shí)間進(jìn)行調(diào)用。
typedef struct { ngx_int_t (*preconfiguration)(ngx_conf_t *cf); ngx_int_t (*postconfiguration)(ngx_conf_t *cf); void *(*create_main_conf)(ngx_conf_t *cf); char *(*init_main_conf)(ngx_conf_t *cf, void *conf); void *(*create_srv_conf)(ngx_conf_t *cf); char *(*merge_srv_conf)(ngx_conf_t *cf, void *prev, void *conf); void *(*create_loc_conf)(ngx_conf_t *cf); char *(*merge_loc_conf)(ngx_conf_t *cf, void *prev, void *conf); } ngx_http_module_t;
- preconfiguration: 在創(chuàng)建和讀取該模塊的配置信息之前被調(diào)用。
- postconfiguration: 在創(chuàng)建和讀取該模塊的配置信息之后被調(diào)用。
- create_main_conf: 調(diào)用該函數(shù)創(chuàng)建本模塊位于 http block 的配置信息存儲(chǔ)結(jié)構(gòu)。該函數(shù)成功的時(shí)候,返回創(chuàng)建的配置對(duì)象。失敗的話(huà),返回 NULL。
- init_main_conf: 調(diào)用該函數(shù)初始化本模塊位于 http block 的配置信息存儲(chǔ)結(jié)構(gòu)。該函數(shù)成功的時(shí)候,返回 NGX_CONF_OK。失敗的話(huà),返回 NGX_CONF_ERROR 或錯(cuò)誤字符串。
- create_srv_conf: 調(diào)用該函數(shù)創(chuàng)建本模塊位于 http server block 的配置信息存儲(chǔ)結(jié)構(gòu),每個(gè) server block 會(huì)創(chuàng)建一個(gè)。該函數(shù)成功的時(shí)候,返回創(chuàng)建的配置對(duì)象。失敗的話(huà),返回 NULL。
- merge_srv_conf: 因?yàn)橛行┡渲弥噶罴瓤梢猿霈F(xiàn)在 http block,也可以出現(xiàn)在 http server block 中。那么遇到這種情況,每個(gè) server 都會(huì)有自己存儲(chǔ)結(jié)構(gòu)來(lái)存儲(chǔ)該 server 的配置,但是在這種情況下 http block 中的配置與 server block 中的配置信息發(fā)生沖突的時(shí)候,就需要調(diào)用此函數(shù)進(jìn)行合并,該函數(shù)并非必須提供,當(dāng)預(yù)計(jì)到絕對(duì)不會(huì)發(fā)生需要合并的情況的時(shí)候,就無(wú)需提供。當(dāng)然為了安全起見(jiàn)還是建議提供。該函數(shù)執(zhí)行成功的時(shí)候,返回 NGX_CONF_OK。失敗的話(huà),返回 NGX_CONF_ERROR 或錯(cuò)誤字符串。
- create_loc_conf: 調(diào)用該函數(shù)創(chuàng)建本模塊位于 location block 的配置信息存儲(chǔ)結(jié)構(gòu)。每個(gè)在配置中指明的 location 創(chuàng)建一個(gè)。該函數(shù)執(zhí)行成功,返回創(chuàng)建的配置對(duì)象。失敗的話(huà),返回 NULL。
- merge_loc_conf: 與 merge_srv_conf 類(lèi)似,這個(gè)也是進(jìn)行配置值合并的地方。該函數(shù)成功的時(shí)候,返回 NGX_CONF_OK。失敗的話(huà),返回 NGX_CONF_ERROR 或錯(cuò)誤字符串。
Nginx 里面的配置信息都是上下一層層的嵌套的,對(duì)于具體某個(gè) location 的話(huà),對(duì)于同一個(gè)配置,如果當(dāng)前層次沒(méi)有定義,那么就使用上層的配置,否則使用當(dāng)前層次的配置。
這些配置信息一般默認(rèn)都應(yīng)該設(shè)為一個(gè)未初始化的值,針對(duì)這個(gè)需求,Nginx 定義了一系列的宏定義來(lái)代表各種配置所對(duì)應(yīng)數(shù)據(jù)類(lèi)型的未初始化值,如下:
#define NGX_CONF_UNSET -1 #define NGX_CONF_UNSET_UINT (ngx_uint_t) -1 #define NGX_CONF_UNSET_PTR (void *) -1 #define NGX_CONF_UNSET_SIZE (size_t) -1 #define NGX_CONF_UNSET_MSEC (ngx_msec_t) -1
又因?yàn)閷?duì)于配置項(xiàng)的合并,邏輯都類(lèi)似,也就是前面已經(jīng)說(shuō)過(guò)的,如果在本層次已經(jīng)配置了,也就是配置項(xiàng)的值已經(jīng)被讀取進(jìn)來(lái)了(那么這些配置項(xiàng)的值就不會(huì)等于上面已經(jīng)定義的那些 UNSET 的值),就使用本層次的值作為定義合并的結(jié)果,否則,使用上層的值,如果上層的值也是這些UNSET類(lèi)的值,那就賦值為默認(rèn)值,否則就使用上層的值作為合并的結(jié)果。對(duì)于這樣類(lèi)似的操作,Nginx 定義了一些宏操作來(lái)做這些事情,我們來(lái)看其中一個(gè)的定義。
#define ngx_conf_merge_uint_value(conf, prev, default) if (conf == NGX_CONF_UNSET_UINT) { conf = (prev == NGX_CONF_UNSET_UINT) ? default : prev; }
顯而易見(jiàn),這個(gè)邏輯確實(shí)比較簡(jiǎn)單,所以其它的宏定義也類(lèi)似,我們就列具其中的一部分吧。
ngx_conf_merge_value ngx_conf_merge_ptr_value ngx_conf_merge_uint_value ngx_conf_merge_msec_value ngx_conf_merge_sec_value
等等。
下面來(lái)看一下 hello 模塊的模塊上下文的定義,加深一下印象。
static ngx_http_module_t ngx_http_hello_module_ctx = { NULL, /* preconfiguration */ ngx_http_hello_init, /* postconfiguration */ NULL, /* create main configuration */ NULL, /* init main configuration */ NULL, /* create server configuration */ NULL, /* merge server configuration */ ngx_http_hello_create_loc_conf, /* create location configuration */ NULL /* merge location configuration */ };
注意:這里并沒(méi)有提供 merge_loc_conf 函數(shù),因?yàn)槲覀冞@個(gè)模塊的配置指令已經(jīng)確定只出現(xiàn)在 NGX_HTTP_LOC_CONF 中這一個(gè)層次上,不會(huì)發(fā)生需要合并的情況。
模塊的定義
對(duì)于開(kāi)發(fā)一個(gè)模塊來(lái)說(shuō),我們都需要定義一個(gè) ngx_module_t 類(lèi)型的變量來(lái)說(shuō)明這個(gè)模塊本身的信息,從某種意義上來(lái)說(shuō),這是這個(gè)模塊最重要的一個(gè)信息,它告訴了 Nginx 這個(gè)模塊的一些信息,上面定義的配置信息,還有模塊上下文信息,都是通過(guò)這個(gè)結(jié)構(gòu)來(lái)告訴 Nginx 系統(tǒng)的,也就是加載模塊的上層代碼,都需要通過(guò)定義的這個(gè)結(jié)構(gòu),來(lái)獲取這些信息。
我們先來(lái)看下 ngx_module_t 的定義
typedef struct ngx_module_s ngx_module_t; struct ngx_module_s { ngx_uint_t ctx_index; ngx_uint_t index; ngx_uint_t spare0; ngx_uint_t spare1; ngx_uint_t abi_compatibility; ngx_uint_t major_version; ngx_uint_t minor_version; void *ctx; ngx_command_t *commands; ngx_uint_t type; ngx_int_t (*init_master)(ngx_log_t *log); ngx_int_t (*init_module)(ngx_cycle_t *cycle); ngx_int_t (*init_process)(ngx_cycle_t *cycle); ngx_int_t (*init_thread)(ngx_cycle_t *cycle); void (*exit_thread)(ngx_cycle_t *cycle); void (*exit_process)(ngx_cycle_t *cycle); void (*exit_master)(ngx_cycle_t *cycle); uintptr_t spare_hook0; uintptr_t spare_hook1; uintptr_t spare_hook2; uintptr_t spare_hook3; uintptr_t spare_hook4; uintptr_t spare_hook5; uintptr_t spare_hook6; uintptr_t spare_hook7; }; #define NGX_NUMBER_MAJOR 3 #define NGX_NUMBER_MINOR 1 #define NGX_MODULE_V1 0, 0, 0, 0, NGX_DSO_ABI_COMPATIBILITY, NGX_NUMBER_MAJOR, NGX_NUMBER_MINOR #define NGX_MODULE_V1_PADDING 0, 0, 0, 0, 0, 0, 0, 0
再看一下 hello 模塊的模塊定義。
ngx_module_t ngx_http_hello_module = { NGX_MODULE_V1, &ngx_http_hello_module_ctx, /* module context */ ngx_http_hello_commands, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init master */ NULL, /* init module */ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ NULL, /* exit process */ NULL, /* exit master */ NGX_MODULE_V1_PADDING };
模塊可以提供一些回調(diào)函數(shù)給 Nginx,當(dāng) Nginx 在創(chuàng)建進(jìn)程線(xiàn)程或者結(jié)束進(jìn)程線(xiàn)程時(shí)進(jìn)行調(diào)用。但大多數(shù)模塊在這些時(shí)刻并不需要做什么,所以都簡(jiǎn)單賦值為 NULL。