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. 序
本文以
1. nginx有哪些模組?
要知道nginx有哪些模組,一個快速的方法就是編譯nginx。編譯之後,會在原始碼根目錄下生成objs目錄,該目錄中包含有ngx_auto_config.h和ngx_auto_headers.h,以及ngx_modules.c檔案,當然,還有Makefile檔案等。
其中,生成的ngx_modules.c檔案中,重新集中申明(使用extern關鍵字)了nginx配置的所有模組,這些模組可通過編譯前的configure
00001:
00002: #include
00003: #include
00004:
00005:
00006:
00007: extern ngx_module_t ngx_core_module;
00008: extern ngx_module_t ngx_errlog_module;
00009: extern ngx_module_t ngx_conf_module;
00010: extern ngx_module_t ngx_events_module;
00011: extern ngx_module_t ngx_event_core_module;
00012: extern ngx_module_t
ngx_epoll_module;00013: extern ngx_module_t ngx_http_module;
00014: extern ngx_module_t ngx_http_core_module;
00015: extern ngx_module_t ngx_http_log_module;
00016: extern ngx_module_t ngx_http_upstream_module;
00017: extern ngx_module_t ngx_http_static_module;
00018: extern ngx_module_t ngx_http_autoindex_module;
00019: extern ngx_module_t ngx_http_index_module;
00020: extern ngx_module_t ngx_http_auth_basic_module;
00021: extern ngx_module_t ngx_http_access_module;
00022: extern ngx_module_t ngx_http_limit_zone_module;
00023: extern ngx_module_t ngx_http_limit_req_module;
00024: extern ngx_module_t ngx_http_geo_module;
00025: extern ngx_module_t ngx_http_map_module;
00026: extern ngx_module_t ngx_http_split_clients_module;
00027: extern ngx_module_t ngx_http_referer_module;
00028: extern ngx_module_t ngx_http_rewrite_module;
00029: extern ngx_module_t ngx_http_proxy_module;
00030: extern ngx_module_t ngx_http_fastcgi_module;
00031: extern ngx_module_t ngx_http_uwsgi_module;
00032: extern ngx_module_t ngx_http_scgi_module;
00033: extern ngx_module_t ngx_http_memcached_module;
00034: extern ngx_module_t ngx_http_empty_gif_module;
00035: extern ngx_module_t ngx_http_browser_module;
00036: extern ngx_module_t ngx_http_upstream_ip_hash_module;
00037: extern ngx_module_t ngx_http_stub_status_module;
00038: extern ngx_module_t ngx_http_write_filter_module;
00039: extern ngx_module_t ngx_http_header_filter_module;
00040: extern ngx_module_t ngx_http_chunked_filter_module;
00041: extern ngx_module_t ngx_http_range_header_filter_module;
00042: extern ngx_module_t ngx_http_gzip_filter_module;
00043: extern ngx_module_t ngx_http_postpone_filter_module;
00044: extern ngx_module_t ngx_http_ssi_filter_module;
00045: extern ngx_module_t ngx_http_charset_filter_module;
00046: extern ngx_module_t ngx_http_userid_filter_module;
00047: extern ngx_module_t ngx_http_headers_filter_module;
00048: extern ngx_module_t ngx_http_copy_filter_module;
00049: extern ngx_module_t ngx_http_range_body_filter_module;
00050: extern ngx_module_t ngx_http_not_modified_filter_module;
00051:
很顯然,這些模組均是在此處用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檔案中定義。如下,//後的內容為筆者加入的注視。
00107: #define NGX_MODULE_V1 0, 0, 0, 0, 0, 0, 1 //該巨集用來初始化前7個欄位
00108: #define NGX_MODULE_V1_PADDING 0, 0, 0, 0, 0, 0, 0, 0 //該巨集用來初始化最後8個欄位
00109:
00110: struct ngx_module_s{
00111: ngx_uint_t ctx_index; //分類模組計數器
00112: ngx_uint_t index; //模組計數器
00113:
00114: ngx_uint_t spare0;
00115: ngx_uint_t spare1;
00116: ngx_uint_t spare2;
00117: ngx_uint_t spare3;
00118:
00119: ngx_uint_t version; //版本
00120:
00121: void *ctx; //該模組的上下文,每個種類的模組有不同的上下文
00122: ngx_command_t *commands; //該模組的命令集,指向一個ngx_command_t結構陣列
00123: ngx_uint_t type; //該模組的種類,為core/event/http/mail中的一種
00124: //以下是一些callback函式
00125: ngx_uint_t (*init_master)(ngx_log_t *log); //初始化master
00126:
00127: ngx_uint_t (*init_module)(ngx_cycle_t *cycle); //初始化模組
00128:
00129: ngx_uint_t (*init_process)(ngx_cycle_t *cycle); //初始化工作程序
00130: ngx_uint_t (*init_thread)(ngx_cycle_t *cycle); //初始化執行緒
00131: void (*exit_thread)(ngx_cycle_t *cycle); //退出執行緒
00132: void (*exit_process)(ngx_cycle_t *cycle); //退出工作程序
00133:
00134: void (*exit_master)(ngx_cycle_t *cycle); //退出master
00135:
00136: uintptr_t spare_hook0; //這些欄位貌似沒用過
00137: uintptr_t spare_hook1;
00138: uintptr_t spare_hook2;
00139: uintptr_t spare_hook3;
00140: uintptr_t spare_hook4;
00141: uintptr_t spare_hook5;
00142: uintptr_t spare_hook6;
00143: uintptr_t spare_hook7;
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檔案中定義。如下,//後的內容為筆者加入的注視。
00077: struct ngx_command_s {
00078: ngx_str_t name; //命令名
00079: ngx_uint_t type; //命令型別
00080: char *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
00081: ngx_uint_t conf;
00082: ngx_uint_t offset;
00083: void *post;
00084: };
00085:
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檔案中的定義。
00052: ngx_module_t *ngx_modules[] = {
00053: &ngx_core_module,
00054: &ngx_errlog_module,
00055: &ngx_conf_module,
00056: &ngx_events_module,
00057: &ngx_event_core_module,
00058: &ngx_epoll_module,
00059: &ngx_http_module,
00060: &ngx_http_core_module,
00061: &ngx_http_log_module,
00062: &ngx_http_upstream_module,
00063: &ngx_http_static_module,
00064: &ngx_http_autoindex_module,
00065: &ngx_http_index_module,
00066: &ngx_http_auth_basic_module,
00067: &ngx_http_access_module,
00068: &ngx_http_limit_zone_module,
00069: &ngx_http_limit_req_module,
00070: &ngx_http_geo_module,
00071: &ngx_http_map_module,
00072: &ngx_http_split_clients_module,
00073: &ngx_http_referer_module,
00074: &ngx_http_rewrite_module,
00075: &ngx_http_proxy_module,
00076: &ngx_http_fastcgi_module,
00077: &ngx_http_uwsgi_module,
00078: &ngx_http_scgi_module,
00079: &ngx_http_memcached_module,
00080: &ngx_http_empty_gif_module,
00081: &ngx_http_browser_module,
00082: &ngx_http_upstream_ip_hash_module,
00083: &ngx_http_stub_status_module,
00084: &ngx_http_write_filter_module,
00085: &ngx_http_header_filter_module,
00086: &ngx_http_chunked_filter_module,
00087: &ngx_http_range_header_filter_module,
00088: &ngx_http_gzip_filter_module,
00089: &ngx_http_postpone_filter_module,
00090: &ngx_http_ssi_filter_module,
00091: &ngx_http_charset_filter_module,
00092: &ngx_http_userid_filter_module,
00093: &ngx_http_headers_filter_module,
00094: &ngx_http_copy_filter_module,
00095: &ngx_http_range_body_filter_module,
00096: &ngx_http_not_modified_filter_module,
00097: NULL
00098: };
00099:
3.2 模組組織結構圖
共44個模組,這些模組的組織結構圖如下所示,因模組較多,圖中只畫出一部分有代表性的重要模組。
4. nginx的模組種類
在對全域性陣列ngx_modules進行初始化時,即對每一個模組進行了靜態初始化。其中對模組的type欄位的初始化是通過以下4個巨集進行的。
(1) 檔案./src/core/ngx_conf_file.h
#defineNGX_CORE_MODULE0x45524F43/* "CORE" */
#defineNGX_CONF_MODULE0x464E4F43/* "CONF" */
(2) 檔案./src/event/ngx_event.h
#define NGX_EVENT_MODULE 0x544E5645 /* "EVNT" */
(3) 檔案./src/http/ngx_http_config.h
#define NGX_HTTP_MODULE 0x50545448 /* "HTTP" */
相關推薦
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如何組織這些模組?
nginx原始碼閱讀(二).初始化:main函式及ngx_init_cycle函式
前言 在分析原始碼時,我們可以先把握主幹,然後其他部分再挨個分析就行了。接下來我們先看看nginx的main函式幹了些什麼。 main函式 這裡先介紹一些下面會遇到的變數型別: ngx_int_t: typedef intptr_t ngx_int_t; 64位機器上,intptr_
SpringMVC原始碼分析--容器初始化(四)FrameworkServlet
一下SpringMVC配置檔案的地址contextConfigLocation的配置屬性,然後其呼叫的子類FrameworkServlet的initServletBean方法。 其實FrameworkServlet是springMVC初始化IOC容器的核心,通過讀取配置的c
springMVC原始碼分析--容器初始化(一)ContextLoaderListener
在spring Web中,需要初始化IOC容器,用於存放我們注入的各種物件。當tomcat啟動時首先會初始化一個web對應的IOC容器,用於初始化和注入各種我們在web執行過程中需要的物件。當tomcat啟動的時候是如何初始化IOC容器的,我們先看一下在web.xml中經常看
SpringMVC原始碼分析--容器初始化(五)DispatcherServlet
上一篇部落格SpringMVC原始碼分析--容器初始化(四)FrameworkServlet我們已經瞭解到了SpringMVC容器的初始化,SpringMVC對容器初始化後會進行一系列的其他屬性的初始化操作,在SpringMVC初始化完成之後會呼叫onRefresh(wac
SpringMVC原始碼分析--容器初始化(三)HttpServletBean
在上一篇部落格 springMVC原始碼分析--容器初始化(二)DispatcherServlet中,我們隊SpringMVC整體生命週期有一個簡單的說明,並沒有進行詳細的原始碼分析,接下來我們會根據部落格中提供的springMVC的生命週期圖來詳細的對SpringMVC的
精盡 MyBatis 原始碼分析 - MyBatis 初始化(一)之載入 mybatis-config.xml
> 該系列文件是本人在學習 Mybatis 的原始碼過程中總結下來的,可能對讀者不太友好,請結合我的原始碼註釋([Mybatis原始碼分析 GitHub 地址](https://github.com/liu844869663/mybatis-3)、[Mybatis-Spring 原始碼分析 GitHub 地址
精盡MyBatis原始碼分析 - MyBatis初始化(二)之載入 Mapper 介面與 XML 對映檔案
> 該系列文件是本人在學習 Mybatis 的原始碼過程中總結下來的,可能對讀者不太友好,請結合我的原始碼註釋([Mybatis原始碼分析 GitHub 地址](https://github.com/liu844869663/mybatis-3)、[Mybatis-Spring 原始碼分析 GitHub 地址
精盡MyBatis原始碼分析 - MyBatis初始化(四)之 SQL 初始化(下)
> 該系列文件是本人在學習 Mybatis 的原始碼過程中總結下來的,可能對讀者不太友好,請結合我的原始碼註釋([Mybatis原始碼分析 GitHub 地址](https://github.com/liu844869663/mybatis-3)、[Mybatis-Spring 原始碼分析 GitHub 地址
nginx原始碼分析(5)——監聽socket初始化
在nginx原始碼分析(4)中,看到了nginx的事件模型,但其中沒有介紹監聽socket的初始化。而對於web server來說,需要通過監聽socket來監聽客戶端的連線等。本篇將會具體介紹這方面的內容。還記得在前文介紹ngx_cycle_t結構時,它具有一個listening屬性,是一個數組,
Nginx原始碼分析與實踐---(一)編寫一個簡單的Http模組
在上一節中,我們通過修改配置檔案,便能讓nginx去訪問我們寫的html檔案,並返回給瀏覽器。問題是:nginx是如何檢測到我們寫的配置項的?檢測到後,nginx又是如何知道該進行什麼操作的? 本節通過親自實踐,寫一個經典的Hello World模組來了解相應的流程是如何進行的。我們採用自上
JFinal初始化分析-常量初始化-1
但是 nts 3.0 nal ring 問題 簡單 環境配置 comment spring自己基本不熟悉,因為超多的xml配置太繁瑣,就放棄了。自己也不是專做開發的,主要工作是運維。jfianl的出現,無xml配置,令人驚喜。 當時就想學一下這個框架的設計,就找博文來讀,但
spring源碼分析之初始化過程
源碼分析 true singleton 存在 factory 源碼 org 包含 eric 1.org.springframework.web.context.ContextLoaderListener 一個ServletContextListener,web容器啟動監聽器
4.4 模組初始化與結束化
4.4.1模組入口程式碼 編譯器為每個Delphi模組(可執行程式、動態連結庫或包)生成模組入口程式碼。同類型的程式或模組,其入口程式碼是相同的。 編譯器為可執行程式.EXE)生成的入口程式碼為: Project1.dpr.9:begin 0044CA9855push ebp 0044C
http模組初始化過程
要理解一個核心部分,模組的初始化概括起來就是申請儲存下一級模組配置結構體的空間,並且呼叫相應的回撥生成模組的配置結構體,然後再開始通過ngx_conf_t指定的內容去解析配置檔案,進行配置指令的儲存 1.ngx_http_module_t 所有http模組都是ngx_http_modul
[Android]高效能MMKV資料互動分析-MMKV初始化
大家好,我係蒼王。 以下是我這個系列的相關文章,有興趣可以參考一下,可以給個喜歡或者關注我的文章。 [Android]如何做一個崩潰率少於千分之三噶應用app--章節列表 元件化群1已經滿員,進來的可以加群2 763094035 MMKV框架初始化 MMKV.initiali
Lumen開發:lumen原始碼解讀之初始化(2)——門面(Facades)與資料庫(db)
緊接上一篇 $app->withFacades();//為應用程式註冊門面。 $app->withEloquent();//為應用程式載入功能強大的庫。 先來看看withFacades() /** * Register the facades
Lumen開發:lumen原始碼解讀之初始化(1)——app例項
先來看看入口檔案public/index.php //請求頭 header('Content-Type: application/json; charset=utf-8'); /* |-------------------------------------------------
twemproxy0.4原理分析-系統初始化過程原理分析
概述 本文介紹twemproxy的系統初始化過程。該過程包括以下幾個方面的內容: 讀取配置檔案,根據配置檔案初始化資料結構 和後臺伺服器建立連線,形成伺服器連線池 初始化事件處理框架,並設定最開始的事件處理函式 建立twemproxy的監聽socket,
Vue原始碼探究-狀態初始化
Vue原始碼探究-狀態初始化 本篇程式碼位於vue/src/core/instance/state.js 繼續隨著核心類的初始化展開探索其他的模組,這一篇來研究一下Vue的狀態初始化。這裡的狀態初始化指的就是在建立例項的時候,在配置物件裡定義的屬性、資料變數、方法等是如何進行初始處理的。由於隨後的資料更新