nginx_0.1.0分析

框架代碼分析

核心模塊

啟動過程(main)

1、全局ngx_cycle_t對象

1、ngx_init_cycle

2、cycle->listening對象數組(ngx_listening_t對象數組)

2、cycle->conf_ctx指針數組

2、各個CORE模塊create_conf創建配置對象,賦值給conf_ctx指針數組

2、ngx_conf_parse解析所有配置文件到conf_ctx指針數組

2、各個CORE模塊init_conf配置缺省默認值

2、ngx_open_listening_sockets監聽端口(數據來源:listening對象數組)

2、所有模塊init_module過程

1、ngx_single_process_cycle

2、所有模塊init_process過程

2、死循環處理事件:ngx_process_events

P.S. http{}解析完,會調用ngx_core_listen_parse將端口信息拷貝到listening對象數組,設置處理函數為ngx_http_init_connection(tcp建鏈完成后的處理函數入口)

配置解析功能(ngx_conf_parse)

(1)如核心模塊中user、group配置(core模塊)

conf_ctx指針數組中指針直接指向配置對象

(2)如events{}中multi_accept配置(event_core模塊)、events配置(epoll模塊)

conf_ctx指針數組中指針指向指針A,指針A指向配置對象指針數組(數組個數為event模塊數,指針數組中各指針指向各event模塊特有的配置對象)

(3)如https{}中配置(event_core模塊)、events配置(epoll模塊)

conf_ctx指針數組中指針指向根ngx_http_conf_ctx_t對象,每個{}信息存儲在獨立的ngx_http_conf_ctx_t對象中,通過鏈表進行級聯)

1、ngx_events_block

1、指針對象、指針數組

1、所有event模塊的create_conf過程

1、ngx_conf_parse嵌套解析events{}中的配置信息

1、所有event模塊的init_conf過程

2、ngx_http_block

1、根ngx_http_conf_ctx_t對象、三個成員指向三個指針數組

1、所有http模塊的pre_conf過程

1、所有http模塊的create_main_conf過程

1、所有http模塊的create_srv_conf過程

1、所有http模塊的create_loc_conf過程

1、ngx_conf_parse嵌套解析https{}中的配置信息

1、各類merge過程定義配置信息作用范圍

1、所有http模塊的init_main_conf過程

1、ngx_core_prepare_phasesconn處理流水線過程(可三方模塊嵌入)

1、ngx_core_listen_parse將端口信息拷貝listening對象數組,設置處理函數為ngx_http_init_connection(tcp建鏈完成后的處理函數入口)

3、ngx_server_block

1、新ngx_http_conf_ctx_t對象、新2個成員指向2個指針數組(main_conf共用)

1、所有http模塊的create_srv_conf過程

1、所有http模塊的create_loc_conf過程

1、ngx_http_core_srv_conf_t對象指針插入根ngx_http_core_main_conf_t對象的servers數組

1、ngx_conf_parse嵌套解析servers{}中的配置信息

1、location排序

4、ngx_location_block

1、新ngx_http_conf_ctx_t對象

1、新loc_conf對象指向1個指針數組(main_conf、srv_conf共用)

1、所有http模塊的create_loc_conf過程

1a、ngx_http_core_loc_conf_t指針插入上層ngx_http_core_srv_conf_t對象的location數組

1b、ngx_http_core_loc_conf_t指針插入上層ngx_http_core_loc_conf_t對象的location數組

1、ngx_conf_parse嵌套解析location{}中的配置信息

舉例NGX_CORE_MODULE模塊NGX_MAIN_CONF配置的解析

1、此時文件未打開,故ngx_open_file打開文件

1、循環用ngx_conf_read_token讀取每一行

1、掃描所有模塊,對指定模塊指定配置進行匹配,并校驗配置個數的正確性

1、NGX_DIRECT_CONF配置是直接使用ngx_core_conf_t對象

2、cmd->set是直接使用ngx_core_conf_t對象

3、如ngx_conf_set_flag_slot

1、NGX_MAIN_CONF配置是指針數組,指向特殊對象內存。如event核心模塊指向event模塊個數組成的指針數組,每個成員指向對應模塊的對象(event_core_t模塊指向event_conf_t對象,epoll_module模塊指向epoll_conf_t對象)

2、cmd->set是指向指針數組(各指針使用各自模塊定義的對象)。

3、如ngx_events_block、ngx_http_block

1、其他配置說明該ngx_conf_parse例程處于嵌套中

2、cmd->set是指向指針數組中,當前模塊對應的定義對象

3、如ngx_event_connections(event_core根模塊中connections配置項)

舉例NGX_HTTP_MODULE模塊NGX_HTTP_MAIN_CONF配置的解析

1、循環用ngx_conf_read_token讀取每一行

1、掃描所有模塊,對指定模塊指定配置進行匹配,并校驗配置個數的正確性

1、其他配置說明該ngx_conf_parse例程處于嵌套中(此時cf->ctx指向起始的ngx_http_conf_ctx_t對象)

2、cmd->set是指向main_conf中,當前模塊對應的定義對象

3、如ngx_conf_set_size_slot(http_core根模塊中connection_pool_size配置項)

3、如ngx_server_block(http_core根模塊中server配置項)

1、ngx_server_block

參數cf指向http_core_main_conf_t對象,cmd指向下面截圖內容:

server{}

2、繼續創建同樣的對象組,調用ngx_conf_parse進行嵌套配置解析NGX_HTTP_SRV_CONF配置(cf->ctx變成新的ngx_http_conf_ctx_t對象)。

舉例NGX_HTTP_MODULE模塊NGX_HTTP_SRV_CONF配置的解析

1、循環用ngx_conf_read_token讀取每一行

1、掃描所有模塊,對指定模塊指定配置進行匹配,并校驗配置個數的正確性

1、其他配置說明該ngx_conf_parse例程處于嵌套中

2、cmd->set是指向srv_conf中,當前模塊對應的定義對象

3、如ngx_conf_set_size_slot(http_core根模塊中listen配置項)

3、如ngx_location_block(http_core根模塊中location配置項)

1、ngx_loc_block

參數cf指向http_core_srv_conf_t對象,cmd指向下面截圖內容:

location{}

2、繼續創建同樣的對象組,調用ngx_conf_parse進行嵌套配置解析NGX_HTTP_LOC_CONF配置(cf->ctx變成新的ngx_http_conf_ctx_t對象)。

舉例NGX_HTTP_MODULE模塊NGX_HTTP_LOC_CONF配置的解析

1、循環用ngx_conf_read_token讀取每一行

1、掃描所有模塊,對指定模塊指定配置進行匹配,并校驗配置個數的正確性

1、其他配置說明該ngx_conf_parse例程處于嵌套中

2、cmd->set是指向srv_conf中,當前模塊對應的定義對象

3、如ngx_set_root(http_core根模塊中alias配置項)

3、如ngx_location_block(http_core根模塊中location配置項)

location是可以無限嵌套的。

總結

文字分析的邏輯往往讓人一頭霧水,圖文并茂才不坑人坑己,配置項影響范圍是由各自模塊去決定的,本文檔討論的均不涉及merge(各種merge函數起始就是把鏈表中的數據merge到外圈里的對象而已,很簡單)。總結:

配置:

配置信息

對象:

配置信息組織形式

代碼:

代碼信息

從代碼可知,http_test配置項可配置在任意{}中,srv_test配置項只能在server{}或location{}中,listen只能在server{}中,loc_test只能在location{}中,對應的對象組成就是上圖所示。

上述總結例子中體現的配置細節不多。其實,http{}中也可以把信息存在loc_conf對象中;http_test存在server{}、location{}中的位置等等。至于作用范圍則是根據你的三方模塊中如何處理merge鉤子了。

配置說明總結

http是最復雜的一個,總結了http模塊,其他的就簡單了。

1、NGX_HTTP_MAIN_CONF、NGX_HTTP_SRV_CONF、NGX_HTTP_LOC_CONF

NGX_HTTP_MAIN_CONF、NGX_HTTP_SRV_CONF、NGX_HTTP_LOC_CONF分別說明該配置項可以出現再http{}、server{}、location{}中。

2、NGX_CONF_NOARGS、NGX_CONF_TAKE1、NGX_CONF_1MORE

說明參數個數,配置校驗使用。

3、NGX_HTTP_MAIN_CONF_OFFSET、NGX_HTTP_SRV_CONF_OFFSET、NGX_HTTP_LOC_CONF_OFFSET

NGX_HTTP_MAIN_CONF_OFFSET、NGX_HTTP_SRV_CONF_OFFSET和NGX_HTTP_LOC_CONF_OFFSET指明該配置信息存儲的數組,不同數組的效果如下(假定配置了NGX_HTTP_MAIN_CONF、NGX_HTTP_SRV_CONF、NGX_HTTP_LOC_CONF參數):

1NGX_HTTP_MAIN_CONF_OFFSET

整個http{}中僅能出現一次,否則會沖突,提示“is duplicate”。

2NGX_HTTP_SRV_CONF_OFFSET

http{}中僅能直接出現一次,嵌套的每個server{}(整個server{})也僅能出現一次,否則會沖突,提示“is duplicate”。

3NGX_HTTP_LOC_CONF_OFFSET

http{}中僅能直接出現一次,嵌套的每個server{}也僅能直接出現一次,任意server中嵌套的每個location{}也僅能直接出現一次,任意location中嵌套的每個location{}也僅能直接出現一次。

event模塊

1、event_core模塊

init_module過程: ngx_event_module_init

1、無

init_process過程:ngx_event_process_ini_t

1、獲取ngx_event_conf_t對象

1、所有event模塊的actions.init過程

1、connections數組、read_events數組、write_events數組

1、端口句柄收信號的處理為ngx_event_accept

1、ngx_add_event添加讀事件(端口句柄)

端口讀處理函數: ngx_event_accept

1、accept生成業務句柄

1、設置句柄屬性

1、ngx_add_conn(如epoll模塊的add_conn函數:)

1、執行listening的handle入口(ngx_http_init_connection)

2、epoll模塊

init_module過程:

init_process過程

actions.init過程:ngx_epoll_init

1、epoll_create創建epoll對象

1、epoll_event數組

1、設置ngx_event_actions事件處理接口為epoll模塊定義的ngx_epoll_module_ctx對象成員

actions.add_conn過程(ngx_add_conn):ngx_epoll_add_connection

端口收到信息,ngx_event_accept就會創建業務句柄,執行句柄的add_conn操作。

1、epoll_ctl添加讀寫事件到epoll對象

actions.add過程(ngx_add_event):ngx_epoll_add_event

添加事件(讀、寫等等)

1、epoll_ctl添加/修改讀/寫事件到epoll對象

http模塊

http_core模塊

init_module過程:

init_process過程

ngx_http_init_connection過程

http_core模塊針對業務句柄的統一入口,設置事件的處理函數。

1、設置寫事件入口為:ngx_http_empty_handler;

1、設置讀事件入口為:ngx_http_init_request(rev);并進入

2、創建ngx_http_connection_t對象

2、創建ngx_http_request_t對象

2、創建讀緩沖區

2、設置讀事件入口為:ngx_http_process_request_line,并進入

3、ngx_http_read_request_header調用connection->recv進行socket讀。

3、ngx_http_parse_request_line解析請求行

3、創建headers_in.headers隊列、headers_in.cookies數組

3、設置讀事件入口為:ngx_http_process_request_headers,并進入

4、ngx_http_read_request_header調用connection->recv進行socket讀。

4、讀完后調用ngx_http_parse_header_line解析請求頭部

4a、頭信息正確,記錄到headers_in.headers隊列

4c、頭信息錯誤,關閉鏈接

4b、頭信息解析完畢,設置讀事件入口為:ngx_http_block_read(終止讀body,先執行流水線)。

4b、ngx_http_handler進入http流水線處理。

ngx_http_handler過程

1、設置寫事件入口為:ngx_http_phase_event_handler

1、執行ngx_http_run_phases

2、(ngx_http_phases定義了階段。每個階段有模塊入口函數組成的數組。)

2、依次執行每個階段。調用各個階段里的函數操作

2、ngx_http_finalize_request請求的收尾工作


階段一:NGX_HTTP_REWRITE_PHASE

ngx_http_rewrite_module模塊負責階段一的工作。

***http_rewrite模塊初始化(init_module):ngx_http_rewrite_init***

設置階段一NGX_HTTP_REWRITE_PHASE的處理入口為函數ngx_http_rewrite_handler

***階段一處理:ngx_http_rewrite_handler***

獲取所有rewrite配置項信息,依次做正則匹配,替換ngx_http_request_t對象的uri。

一般回復NGX_DECLINED狀態進入下一個階段一處理(沒有),最后進入階段二。


階段二:NGX_HTTP_FIND_CONFIG_PHASE

ngx_http_block中已經設置NGX_HTTP_FIND_CONFIG_PHASE的處理入口函數為ngx_http_find_location_config

***階段二處理:ngx_http_find_location_config***

使用ngx_http_request_t對象的uri成員去匹配配置文件中的location{}信息,將匹配到的location信息記錄到loc_conf成員。(配置代理模式(ngx_http_proxy_module模塊的proxy_pass配置項)時,設置content_handler為ngx_http_proxy_handler;配置重定向模式(ngx_http_rewrite_module模塊redirect配置項)時,設置content_handler為ngx_http_redirect_handler,要細研究下)


階段三:NGX_HTTP_ACCESS_PHASE

ngx_http_access_module模塊負責階段三的工作。

***ngx_http_access_module模塊初始化(init_module):ngx_http_access_init***

***階段三處理:ngx_http_access_handler***

匹配ngx_http_access_commands模塊的allow配置項,則通過權限驗證;

匹配ngx_http_access_commands模塊的deny配置項,則不通過權限驗證;


階段四:NGX_HTTP_CONTENT_PHASE

ngx_http_index_module模塊和ngx_http_static_module模塊負責階段四的工作。

(排在前面的后執行,排在后面的先執行)

***模塊初始化(init_module):ngx_http_index_init、ngx_http_static_init***

***階段四處理1ngx_http_index_handler***

1、創建ngx_http_index_ctx_t對象(r->ctx[ngx_http_index_module])

1、

***階段四處理2ngx_http_static_handler***

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,002評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,400評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,136評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,714評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,452評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,818評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,812評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,997評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,552評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,292評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,510評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,035評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,721評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,121評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,429評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,235評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,480評論 2 379

推薦閱讀更多精彩內容