nginx源码分析—模块及其初始化
Content
0. 序
1. nginx有哪些模塊?
2. nginx如何描述這些模塊?
2.1 模塊數據結構
2.1.1 ngx_module_t結構
2.1.2 ngx_command_t結構
2.2 模塊類圖
3. nginx如何組織這些模塊?
3.1 全局數組ngx_modules
3.2 模塊組織結構圖
4. nginx的模塊種類
5. nginx如何初始化這些模塊?
5.1 靜態初始化
5.2 動態初始化
5.2.1 index字段的初始化
5.2.2 ctx_index字段的初始化
5.2.3 其他初始化
6. 小結
??
0. 序
?
本文以nginx-1.0.4版本為例,介紹nginx的模塊及其初始化。.表示nginx-1.0.4源代碼目錄,本文為/usr/src/nginx-1.0.4。
?
1. nginx有哪些模塊?
?
要知道nginx有哪些模塊,一個快速的方法就是編譯nginx。編譯之后,會在源代碼根目錄下生成objs目錄,該目錄中包含有ngx_auto_config.h和ngx_auto_headers.h,以及ngx_modules.c文件,當然,還有Makefile文件等。
?
其中,生成的ngx_modules.c文件中,重新集中申明(使用extern關鍵字)了nginx配置的所有模塊,這些模塊可通過編譯前的configure命令進行配置,即設置哪些模塊需要編譯,哪些不被編譯。如下。
?
1 00001: 2 00002: #include <ngx_config.h> 3 00003: #include <ngx_core.h> 4 00004: 5 00005: 6 00006: 7 00007: extern ngx_module_t ngx_core_module; 8 00008: extern ngx_module_t ngx_errlog_module; 9 00009: extern ngx_module_t ngx_conf_module; 10 00010: extern ngx_module_t ngx_events_module; 11 00011: extern ngx_module_t ngx_event_core_module; 12 00012: extern ngx_module_t ngx_epoll_module; 13 00013: extern ngx_module_t ngx_http_module; 14 00014: extern ngx_module_t ngx_http_core_module; 15 00015: extern ngx_module_t ngx_http_log_module; 16 00016: extern ngx_module_t ngx_http_upstream_module; 17 00017: extern ngx_module_t ngx_http_static_module; 18 00018: extern ngx_module_t ngx_http_autoindex_module; 19 00019: extern ngx_module_t ngx_http_index_module; 20 00020: extern ngx_module_t ngx_http_auth_basic_module; 21 00021: extern ngx_module_t ngx_http_access_module; 22 00022: extern ngx_module_t ngx_http_limit_zone_module; 23 00023: extern ngx_module_t ngx_http_limit_req_module; 24 00024: extern ngx_module_t ngx_http_geo_module; 25 00025: extern ngx_module_t ngx_http_map_module; 26 00026: extern ngx_module_t ngx_http_split_clients_module; 27 00027: extern ngx_module_t ngx_http_referer_module; 28 00028: extern ngx_module_t ngx_http_rewrite_module; 29 00029: extern ngx_module_t ngx_http_proxy_module; 30 00030: extern ngx_module_t ngx_http_fastcgi_module; 31 00031: extern ngx_module_t ngx_http_uwsgi_module; 32 00032: extern ngx_module_t ngx_http_scgi_module; 33 00033: extern ngx_module_t ngx_http_memcached_module; 34 00034: extern ngx_module_t ngx_http_empty_gif_module; 35 00035: extern ngx_module_t ngx_http_browser_module; 36 00036: extern ngx_module_t ngx_http_upstream_ip_hash_module; 37 00037: extern ngx_module_t ngx_http_stub_status_module; 38 00038: extern ngx_module_t ngx_http_write_filter_module; 39 00039: extern ngx_module_t ngx_http_header_filter_module; 40 00040: extern ngx_module_t ngx_http_chunked_filter_module; 41 00041: extern ngx_module_t ngx_http_range_header_filter_module; 42 00042: extern ngx_module_t ngx_http_gzip_filter_module; 43 00043: extern ngx_module_t ngx_http_postpone_filter_module; 44 00044: extern ngx_module_t ngx_http_ssi_filter_module; 45 00045: extern ngx_module_t ngx_http_charset_filter_module; 46 00046: extern ngx_module_t ngx_http_userid_filter_module; 47 00047: extern ngx_module_t ngx_http_headers_filter_module; 48 00048: extern ngx_module_t ngx_http_copy_filter_module; 49 00049: extern ngx_module_t ngx_http_range_body_filter_module; 50 00050: extern ngx_module_t ngx_http_not_modified_filter_module; 51 00051: View Code?
很顯然,這些模塊均是在此處用extern進行申明,以表明其他模塊可以訪問,而對其本身的定義和初始化ngx_module_t結構在其對應的.c文件中進行。例如,ngx_core_module模塊便是在./src/core/nginx.c文件中定義并進行靜態初始化。實際上,ngx_core_module是一個全局的結構體對象,其他模塊類同。如下。
?
ngx_module_t ngx_core_module = {NGX_MODULE_V1,&ngx_core_module_ctx, /* module context */ngx_core_commands, /* module directives */NGX_CORE_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 };?
?
2. nginx如何描述這些模塊?
?
2.1 模塊數據結構
?
2.1.1 ngx_module_t結構
?
nginx的模塊化架構最基本的數據結構為ngx_module_t,因此,此處,我們先分析這個結構,在./src/core/ngx_conf_file.h文件中定義。如下,//后的內容為筆者加入的注釋。
?
1 00107: #define NGX_MODULE_V1 0, 0, 0, 0, 0, 0, 1 //該宏用來初始化前7個字段 2 00108: #define NGX_MODULE_V1_PADDING 0, 0, 0, 0, 0, 0, 0, 0 //該宏用來初始化最后8個字段 3 00109: 4 00110: struct ngx_module_s{ 5 00111: ngx_uint_t ctx_index; //分類模塊計數器 6 00112: ngx_uint_t index; //模塊計數器 7 00113: 8 00114: ngx_uint_t spare0; 9 00115: ngx_uint_t spare1; 10 00116: ngx_uint_t spare2; 11 00117: ngx_uint_t spare3; 12 00118: 13 00119: ngx_uint_t version; //版本 14 00120: 15 00121: void *ctx; //該模塊的上下文,每個種類的模塊有不同的上下文 16 00122: ngx_command_t *commands; //該模塊的命令集,指向一個ngx_command_t結構數組 17 00123: ngx_uint_t type; //該模塊的種類,為core/event/http/mail中的一種 18 00124: //以下是一些callback函數 19 00125: ngx_uint_t (*init_master)(ngx_log_t *log); //初始化master 20 00126: 21 00127: ngx_uint_t (*init_module)(ngx_cycle_t *cycle); //初始化模塊 22 00128: 23 00129: ngx_uint_t (*init_process)(ngx_cycle_t *cycle); //初始化工作進程 24 00130: ngx_uint_t (*init_thread)(ngx_cycle_t *cycle); //初始化線程 25 00131: void (*exit_thread)(ngx_cycle_t *cycle); //退出線程 26 00132: void (*exit_process)(ngx_cycle_t *cycle); //退出工作進程 27 00133: 28 00134: void (*exit_master)(ngx_cycle_t *cycle); //退出master 29 00135: 30 00136: uintptr_t spare_hook0; //這些字段貌似沒用過 31 00137: uintptr_t spare_hook1; 32 00138: uintptr_t spare_hook2; 33 00139: uintptr_t spare_hook3; 34 00140: uintptr_t spare_hook4; 35 00141: uintptr_t spare_hook5; 36 00142: uintptr_t spare_hook6; 37 00143: uintptr_t spare_hook7; 38 00144: };?
其中,init_master, init_module, init_process, init_thread, exit_thread, exit_process, exit_master分別在初始化master、初始化模塊、初始化工作進程、初始化線程、退出線程、退出工作進程、退出master時被調用。
?
2.1.2 ngx_command_t結構
?
模塊的命令集commands指向一個ngx_command_t結構數組,在./src/core/ngx_conf_file.h文件中定義。如下,//后的內容為筆者加入的注釋。
?
1 00077: struct ngx_command_s { 2 00078: ngx_str_t name; //命令名 3 00079: ngx_uint_t type; //命令類型 4 00080: char *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); 5 00081: ngx_uint_t conf; 6 00082: ngx_uint_t offset; 7 00083: void *post; 8 00084: }; 9 00085: 10 00086: #define ngx_null_command { ngx_null_string, 0, NULL, 0, 0, NULL } //空命令?
2.2 模塊類圖
?
nginx為C語言開發的開源高性能web server,其代碼中大量使用了callback方式,例如模塊結構ngx_module_t中的init_master等。實際上,我們可以將ngx_module_t看作C++的一個類,其中的數據字段便是其屬性,而那些callback便是該類的操作。
?
——這應該就是nginx的模塊化思想。畫出的ngx_module_t的類圖如下。
3.nginx如何組織這些模塊?
?
3.1 全局數組ngx_modules
?
由第1節,我們知道,nginx擁有幾十個模塊,那么,這些模塊是如何組織的呢?
?
——保存在一個全局指針數組ngx_modules[]中,數組的每一個元素均為一個全局ngx_module_t對象的指針。如下。請參考./objs/ngx_modules.c文件中的定義。
?
1 00052: ngx_module_t *ngx_modules[] = { 2 00053: &ngx_core_module, 3 00054: &ngx_errlog_module, 4 00055: &ngx_conf_module, 5 00056: &ngx_events_module, 6 00057: &ngx_event_core_module, 7 00058: &ngx_epoll_module, 8 00059: &ngx_http_module, 9 00060: &ngx_http_core_module, 10 00061: &ngx_http_log_module, 11 00062: &ngx_http_upstream_module, 12 00063: &ngx_http_static_module, 13 00064: &ngx_http_autoindex_module, 14 00065: &ngx_http_index_module, 15 00066: &ngx_http_auth_basic_module, 16 00067: &ngx_http_access_module, 17 00068: &ngx_http_limit_zone_module, 18 00069: &ngx_http_limit_req_module, 19 00070: &ngx_http_geo_module, 20 00071: &ngx_http_map_module, 21 00072: &ngx_http_split_clients_module, 22 00073: &ngx_http_referer_module, 23 00074: &ngx_http_rewrite_module, 24 00075: &ngx_http_proxy_module, 25 00076: &ngx_http_fastcgi_module, 26 00077: &ngx_http_uwsgi_module, 27 00078: &ngx_http_scgi_module, 28 00079: &ngx_http_memcached_module, 29 00080: &ngx_http_empty_gif_module, 30 00081: &ngx_http_browser_module, 31 00082: &ngx_http_upstream_ip_hash_module, 32 00083: &ngx_http_stub_status_module, 33 00084: &ngx_http_write_filter_module, 34 00085: &ngx_http_header_filter_module, 35 00086: &ngx_http_chunked_filter_module, 36 00087: &ngx_http_range_header_filter_module, 37 00088: &ngx_http_gzip_filter_module, 38 00089: &ngx_http_postpone_filter_module, 39 00090: &ngx_http_ssi_filter_module, 40 00091: &ngx_http_charset_filter_module, 41 00092: &ngx_http_userid_filter_module, 42 00093: &ngx_http_headers_filter_module, 43 00094: &ngx_http_copy_filter_module, 44 00095: &ngx_http_range_body_filter_module, 45 00096: &ngx_http_not_modified_filter_module, 46 00097: NULL 47 00098: }; 48 00099:?
3.2 模塊組織結構圖
?
共44個模塊,這些模塊的組織結構圖如下所示,因模塊較多,圖中只畫出一部分有代表性的重要模塊。?
4. nginx的模塊種類
?
在對全局數組ngx_modules進行初始化時,即對每一個模塊進行了靜態初始化。其中對模塊的type字段的初始化是通過以下4個宏進行的。
?
(1) 文件./src/core/ngx_conf_file.h
?
1 #define NGX_CORE_MODULE 0x45524F43 /* "CORE" */ 2 #define NGX_CONF_MODULE 0x464E4F43 /* "CONF" */?
(2) 文件./src/event/ngx_event.h
?
1 #define NGX_EVENT_MODULE 0x544E5645 /* "EVNT" */ 2 #define NGX_EVENT_MODULE 0x544E5645 /* "EVNT" */?
(3) 文件./src/http/ngx_http_config.h
?
1 #define NGX_HTTP_MODULE 0x50545448 /* "HTTP" */?
即模塊種類宏,定義為一個十六進制的數,這個十六進制的數就是其類型對應的ASCII碼。因此,nginx共有4種類型的模塊,分別為"CORE","CONF","EVNT","HTTP"。
?
實際上,如果在configure階段,使用了"--with-mail"參數,mail模塊將被編譯進來,其對應的宏如下。
?
1 #define NGX_MAIL_MODULE 0x4C49414D /* "MAIL" */?
因此,嚴格來講,nginx有5中類型的模塊,"CORE","CONF","EVNT","HTTP","MAIL"。
5. nginx如何初始化這些模塊?
?
5.1 靜態初始化
?
即編譯期間完成的數據成員初始化。記mname為某個模塊的名字,其靜態初始化過程如下。
(1) 用宏NGX_MODULE_V1初始化前7個字段
(2) 用全局對象ngx_mname_module_ctx的地址初始化ctx指針
(3) 用全局數組ngx_mname_commands[]初始化commands指針
(4) 用宏NGX_CORE_MODULE等初始化type字段
(5) 初始化init_master等callback
(6) 用宏NGX_MODULE_V1_PADDING初始化最后8個字段
?
由此可見,在定義該模塊(全局結構對象)時,將其ctx_index和index均初始化為0。因此,模塊的靜態初始化(數據成員初始化)實際上只是對模塊上下文、模塊命令集和模塊類型進行初始化。
?
5.2動態初始化
?
即nginx運行(啟動)初期,對模塊本身的初始化。
?
5.2.1 index字段的初始化
?
?
?
對各個模塊的index字段的初始化是在main函數中進行的,如下。
?
00325: ngx_max_module = 0; 00326: for (i = 0; ngx_modules[i]; i++) { 00327: ngx_modules[i]->index = ngx_max_module++; 00328: }?
?
可見,該for-loop執行后,每個模塊的index值便是其在ngx_modules[]數組中的下標值,且全局變量ngx_max_module為模塊個數,對于本例來講,ngx_max_module=44。
?
5.2.2 ctx_index字段的初始化
?
(1) "EVNT"類型的模塊
?
1 00877: static char * 2 00878: ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 3 00879: { 4 00880: char *rv; 5 00881: void ***ctx; 6 00882: ngx_uint_t i; 7 00883: ngx_conf_t pcf; 8 00884: ngx_event_module_t *m; 9 00885: 10 00886: /* count the number of the event modules and set up their indices */ 11 00887: 12 00888: ngx_event_max_module = 0; 13 00889: for (i = 0; ngx_modules[i]; i++) { 14 00890: if (ngx_modules[i]->type ! = NGX_EVENT_MODULE) { 15 00891: continue; 16 00892: } 17 00893: 18 00894: ngx_modules[i]->ctx_index = ngx_event_max_module++; 19 00895: } 20 00896: 21 ...?
5.2.3其他初始化
?
其他的初始化工作,將在nginx啟動及其進程啟動分析中介紹。
?
6. 小結
?
本文主要講述了nginx的模塊及其初始化,包括所有模塊的組織,及模塊的靜態初始化和部分動態初始化。
?
?
Reference
nginx-1.0.4源碼
http://nginx.org/en
?
?
?
?
?
?
?
?
?
?
?
?
轉載于:https://www.cnblogs.com/canxuexiecheng/articles/3276551.html
總結
以上是生活随笔為你收集整理的nginx源码分析—模块及其初始化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: XHTML重构(一)
- 下一篇: 《BI项目笔记》多维数据集中度量值设计时