這篇文章主要介紹“Nginx請(qǐng)求處理流程是怎樣的”,在日常操作中,相信很多人在Nginx請(qǐng)求處理流程是怎樣的問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”Nginx請(qǐng)求處理流程是怎樣的”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!
成都創(chuàng)新互聯(lián)公司專(zhuān)注于網(wǎng)站建設(shè)|網(wǎng)站維護(hù)|優(yōu)化|托管以及網(wǎng)絡(luò)推廣,積累了大量的網(wǎng)站設(shè)計(jì)與制作經(jīng)驗(yàn),為許多企業(yè)提供了網(wǎng)站定制設(shè)計(jì)服務(wù),案例作品覆蓋陽(yáng)臺(tái)護(hù)欄等行業(yè)。能根據(jù)企業(yè)所處的行業(yè)與銷(xiāo)售的產(chǎn)品,結(jié)合品牌形象的塑造,量身制作品質(zhì)網(wǎng)站。
1)NGX_HTTP_POST_READ_PHASE:
接收到完整的HTTP頭部后處理的階段,它位于uri重寫(xiě)之前,實(shí)際上很少有模塊會(huì)注冊(cè)在該階段,默認(rèn)的情況下,該階段被跳過(guò)。
2)NGX_HTTP_SERVER_REWRITE_PHASE:
URI與location匹配前,修改URI的階段,用于重定向,也就是該階段執(zhí)行處于server塊內(nèi),location塊外的重寫(xiě)指令,在讀取請(qǐng)求頭的過(guò)程中nginx會(huì)根據(jù)host及端口找到對(duì)應(yīng)的虛擬主機(jī)配置。
3)NGX_HTTP_FIND_CONFIG_PHASE:
根據(jù)URI尋找匹配的location塊配置項(xiàng)階段,該階段使用重寫(xiě)之后的uri來(lái)查找對(duì)應(yīng)的location,值得注意的是該階段可能會(huì)被執(zhí)行多次,因?yàn)橐部赡苡衛(wèi)ocation級(jí)別的重寫(xiě)指令。
4)NGX_HTTP_REWRITE_PHASE:
上一階段找到location塊后再修改URI,location級(jí)別的uri重寫(xiě)階段,該階段執(zhí)行l(wèi)ocation基本的重寫(xiě)指令,也可能會(huì)被執(zhí)行多次。
5)NGX_HTTP_POST_REWRITE_PHASE:
防止重寫(xiě)URL后導(dǎo)致的死循環(huán),location級(jí)別重寫(xiě)的后一階段,用來(lái)檢查上階段是否有uri重寫(xiě),并根據(jù)結(jié)果跳轉(zhuǎn)到合適的階段。
6)NGX_HTTP_PREACCESS_PHASE:
下一階段之前的準(zhǔn)備,訪(fǎng)問(wèn)權(quán)限控制的前一階段,該階段在權(quán)限控制階段之前,一般也用于訪(fǎng)問(wèn)控制,比如限制訪(fǎng)問(wèn)頻率,鏈接數(shù)等。
7)NGX_HTTP_ACCESS_PHASE:
讓HTTP模塊判斷是否允許這個(gè)請(qǐng)求進(jìn)入Nginx服務(wù)器,訪(fǎng)問(wèn)權(quán)限控制階段,比如基于ip黑白名單的權(quán)限控制,基于用戶(hù)名密碼的權(quán)限控制等。
8)NGX_HTTP_POST_ACCESS_PHASE:
訪(fǎng)問(wèn)權(quán)限控制的后一階段,該階段根據(jù)權(quán)限控制階段的執(zhí)行結(jié)果進(jìn)行相應(yīng)處理,向用戶(hù)發(fā)送拒絕服務(wù)的錯(cuò)誤碼,用來(lái)響應(yīng)上一階段的拒絕。
9)NGX_HTTP_TRY_FILES_PHASE:
為訪(fǎng)問(wèn)靜態(tài)文件資源而設(shè)置,try_files指令的處理階段,如果沒(méi)有配置try_files指令,則該階段被跳過(guò)。
10)NGX_HTTP_CONTENT_PHASE:
處理HTTP請(qǐng)求內(nèi)容的階段,大部分HTTP模塊介入這個(gè)階段,內(nèi)容生成階段,該階段產(chǎn)生響應(yīng),并發(fā)送到客戶(hù)端。
11)NGX_HTTP_LOG_PHASE:
處理完請(qǐng)求后的日志記錄階段,該階段記錄訪(fǎng)問(wèn)日志。
以上11個(gè)階段中,HTTP無(wú)法介入的階段有4個(gè):
3)NGX_HTTP_FIND_CONFIG_PHASE
5)NGX_HTTP_POST_REWRITE_PHASE
8)NGX_HTTP_POST_ACCESS_PHASE
9)NGX_HTTP_TRY_FILES_PHASE
剩余的7個(gè)階段,HTTP模塊均能介入,每個(gè)階段可介入模塊的個(gè)數(shù)也是沒(méi)有限制的,多個(gè)HTTP模塊可同時(shí)介入同一階段并作用于同一請(qǐng)求。
typedef structngx_http_phase_handler_s ngx_http_phase_handler_t;/*一個(gè)HTTP處理階段中的checker檢查方法,僅可以由HTTP框架實(shí)現(xiàn),以此控制HTTP請(qǐng)求的處理流程*/typedef ngx_int_t(*ngx_http_phase_handler_pt)(ngx_http_request_t *r, ngx_http_phase_handler_t*ph);/*由HTTP模塊實(shí)現(xiàn)的handler處理方法*/typedef ngx_int_t(*ngx_http_handler_pt)(ngx_http_request_t *r); struct ngx_http_phase_handler_s { /*在處理到某一個(gè)HTTP階段時(shí),HTTP框架將會(huì)在checker方法已實(shí)現(xiàn)的前提下首先調(diào)用checker方法來(lái)處理請(qǐng)求, 而不會(huì)直接調(diào)用任何階段中的hanlder方法,只有在checker方法中才會(huì)去調(diào)用handler方法,因此,事實(shí)上所有 的checker方法都是由框架中的ngx_http_core_module模塊實(shí)現(xiàn)的,且普通模塊無(wú)法重定義checker方法*/ ngx_http_phase_handler_pt checker; /*除ngx_http_core_module模塊以外的HTTP模塊,只能通過(guò)定義handler方法才能介入某一個(gè)HTTP處理階段以處理請(qǐng)求*/ ngx_http_handler_pt handler; /*將要處理的下一個(gè)HTTP處理階段的序號(hào) next的設(shè)計(jì)使得處理階段不必按順序依次執(zhí)行,既可以向后跳躍數(shù)個(gè)階段繼續(xù)執(zhí)行,也可以跳躍到之前的某個(gè)階段重新 執(zhí)行,通常,next表示下一個(gè)處理階段中的第1個(gè)ngx_http_phase_handler_t處理方法*/ ngx_uint_t next; };
一個(gè)http{}塊解析完畢后,將會(huì)根據(jù)nginx.conf中的配置產(chǎn)生由ngx_http_phase_handler_t組成的數(shù)組,在處理HTTP請(qǐng)求時(shí),一般情況下這些階段是順序向后執(zhí)行的,但ngx_http_phase_handler_t中的next成員使得它們也可以非順序地執(zhí)行,ngx_http_phase_engine_t結(jié)構(gòu)體就是所有ngx_http_phase_handler_t組成的數(shù)組,如下所示:
typedef struct { /*handlers是由ngx_http_phase_handler_t構(gòu)成的數(shù)組首地址,它表示一個(gè)請(qǐng)求可能經(jīng)歷的所有ngx_http_handler_pt處理方法*/ ngx_http_phase_handler_t *handlers; /*表示NGX_HTTP_SERVER_REWRITE_PHASE階段第1個(gè)ngx_http_phase_handler_t處理方法在handlers數(shù)組中的序號(hào),用于在執(zhí)行 HTTP請(qǐng)求的任何階段中快速跳轉(zhuǎn)到HTTP_SERVER_REWRITE_PHASE階段處理請(qǐng)求*/ ngx_uint_t server_rewrite_index; /*表示NGX_HTTP_PREACCESS_PHASE階段第1個(gè)ngx_http_phase_handler_t處理方法在handlers數(shù)組中的序號(hào),用于在執(zhí)行 HTTP請(qǐng)求的任何階段中快速跳轉(zhuǎn)到NGX_HTTP_PREACCESS_PHASE階段處理請(qǐng)求*/ ngx_uint_t location_rewrite_index; } ngx_http_phase_engine_t;
可以看到,ngx_http_phase_engine_t中保存了在當(dāng)前nginx.conf配置下,一個(gè)用戶(hù)請(qǐng)求可能經(jīng)歷的所有ngx_http_handler_pt處理方法,這是所有HTTP模塊可以合作處理用戶(hù)請(qǐng)求的關(guān)鍵,這個(gè)ngx_http_phase_engine_t結(jié)構(gòu)體保存在全局的ngx_http_core_main_conf_t結(jié)構(gòu)體中,如下:
typedef struct { ngx_array_t servers; /* ngx_http_core_srv_conf_t */ /*由下面各階段處理方法構(gòu)成的phases數(shù)組構(gòu)建的階段引擎才是流水式處理HTTP請(qǐng)求的實(shí)際數(shù)據(jù)結(jié)構(gòu)*/ ngx_http_phase_engine_t phase_engine; ngx_hash_t headers_in_hash; ngx_hash_t variables_hash; ngx_array_t variables; /* ngx_http_variable_t */ ngx_uint_t ncaptures; ngx_uint_t server_names_hash_max_size; ngx_uint_t server_names_hash_bucket_size; ngx_uint_t variables_hash_max_size; ngx_uint_t variables_hash_bucket_size; ngx_hash_keys_arrays_t *variables_keys; ngx_array_t *ports; ngx_uint_t try_files; /* unsigned try_files:1 */ /*用于在HTTP框架初始化時(shí)幫助各個(gè)HTTP模塊在任意階段中添加HTTP處理方法,它是一個(gè)有11個(gè)成員的ngx_http_phase_t數(shù)組, 其中每一個(gè)ngx_http_phase_t結(jié)構(gòu)體對(duì)應(yīng)一個(gè)HTTP階段,在HTTP框架初始化完畢后,運(yùn)行過(guò)程中的phases數(shù)組是無(wú)用的*/ ngx_http_phase_t phases[NGX_HTTP_LOG_PHASE + 1]; } ngx_http_core_main_conf_t;
在ngx_http_phase_t中關(guān)于HTTP階段有兩個(gè)成員:phase_engine和phases,其中phase_engine控制運(yùn)行過(guò)程中的一個(gè)HTTP請(qǐng)求所要經(jīng)過(guò)的HTTP處理階段,它將配合ngx_http_request_t結(jié)構(gòu)體中的phase_handler成員使用(phase_handler制定了當(dāng)前請(qǐng)求應(yīng)當(dāng)執(zhí)行哪一個(gè)HTTP階段);而phases數(shù)組更像一個(gè)臨時(shí)變量,它實(shí)際上僅會(huì)在Nginx啟動(dòng)過(guò)程中用到,它的唯一使命是按照11個(gè)階段的概率初始化phase_engine中的handlers數(shù)組。
typedef struct { /*handlers動(dòng)態(tài)數(shù)組保存著每一個(gè)HTTP模塊初始化時(shí)添加到當(dāng)前階段的處理方法*/ ngx_array_t handlers; } ngx_http_phase_t;
在HTTP框架的初始化過(guò)程中,任何HTTP模塊都可以在ngx_http_module_t接口的postconfiguration方法中將自定義的方法添加到handler動(dòng)態(tài)數(shù)組中,這樣,這個(gè)方法就會(huì)最終添加到phase_engine動(dòng)態(tài)數(shù)組中。
init_by_lua http
set_by_lua server, server if, location, location if
rewrite_by_lua http, server, location, location if
access_by_lua http, server, location, location if
content_by_lua location, location if
header_filter_by_lua http, server, location, location if
body_filter_by_lua http, server, location, location if
log_by_lua http, server, location, location if
1)init_by_lua:
在nginx重新加載配置文件時(shí),運(yùn)行里面lua腳本,常用于全局變量的申請(qǐng)。(例如:lua_shared_dict共享內(nèi)存的申請(qǐng),只有當(dāng)nginx重起后,共享內(nèi)存數(shù)據(jù)才清空,這常用于統(tǒng)計(jì)。)
2)set_by_lua:
流程分支處理判斷變量初始化(設(shè)置一個(gè)變量,常用與計(jì)算一個(gè)邏輯,然后返回結(jié)果,該階段不能運(yùn)行Output API、Control API、Subrequest API、Cosocket API)
3)rewrite_by_lua:
轉(zhuǎn)發(fā)、重定向、緩存等功能 (例如特定請(qǐng)求代理到外網(wǎng),在access階段前運(yùn)行,主要用于rewrite)
4)access_by_lua:
IP準(zhǔn)入、接口權(quán)限等情況集中處理(例如配合iptable完成簡(jiǎn)單防火墻,主要用于訪(fǎng)問(wèn)控制,能收集到大部分變量,類(lèi)似status需要在log階段才有。這條指令運(yùn)行于nginx access階段的末尾,因此總是在 allow 和 deny 這樣的指令之后運(yùn)行,雖然它們同屬 access 階段。)
5)content_by_lua:
內(nèi)容生成,階段是所有請(qǐng)求處理階段中最為重要的一個(gè),運(yùn)行在這個(gè)階段的配置指令一般都肩負(fù)著生成內(nèi)容(content)并輸出HTTP響應(yīng)。
6)header_filter_by_lua:
應(yīng)答HTTP過(guò)濾處理,一般只用于設(shè)置Cookie和Headers等,該階段不能運(yùn)行Output API、Control API、Subrequest API、Cosocket API(例如添加頭部信息)。
7)body_filter_by_lua:
應(yīng)答B(yǎng)ODY過(guò)濾處理(例如完成應(yīng)答內(nèi)容統(tǒng)一成大寫(xiě))(一般會(huì)在一次請(qǐng)求中被調(diào)用多次, 因?yàn)檫@是實(shí)現(xiàn)基于 HTTP 1.1 chunked 編碼的所謂“流式輸出”的,該階段不能運(yùn)行Output API、Control API、Subrequest API、Cosocket API)
8)log_by_lua:
會(huì)話(huà)完成后本地異步完成日志記錄(日志可以記錄在本地,還可以同步到其他機(jī)器)(該階段總是運(yùn)行在請(qǐng)求結(jié)束的時(shí)候,用于請(qǐng)求的后續(xù)操作,如在共享內(nèi)存中進(jìn)行統(tǒng)計(jì)數(shù)據(jù),如果要高精確的數(shù)據(jù)統(tǒng)計(jì),應(yīng)該使用body_filter_by_lua,該階段不能運(yùn)行Output API、Control API、Subrequest API、Cosocket API)
三 nginx和lua運(yùn)行階段的對(duì)應(yīng)關(guān)系
1)init_by_lua,運(yùn)行在initialization Phase;
2)set_by_lua,運(yùn)行在rewrite 階段;
set 指令來(lái)自 ngx_rewrite 模塊,運(yùn)行于 rewrite 階段;
3)rewrite_by_lua 指令來(lái)自 ngx_lua 模塊,運(yùn)行于 rewrite 階段的末尾
4)access_by_lua 指令同樣來(lái)自 ngx_lua 模塊,運(yùn)行于 access 階段的末尾;
deny 指令來(lái)自 ngx_access 模塊,運(yùn)行于 access 階段;
5)content_by_lua 指令來(lái)自 ngx_lua 模塊,運(yùn)行于 content 階段;不要將它和其它的內(nèi)容處理指令在同一個(gè)location內(nèi)使用如proxy_pass;
echo 指令則來(lái)自 ngx_echo 模塊,運(yùn)行在 content 階段;
6)header_filter_by_lua 運(yùn)行于 content 階段,output-header-filter 一般用來(lái)設(shè)置cookie和headers;
7)body_filter_by_lua,運(yùn)行于 content 階段;
8)log_by_lua,運(yùn)行在Log Phase 階段;
如圖:
到此,關(guān)于“Nginx請(qǐng)求處理流程是怎樣的”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!
網(wǎng)站標(biāo)題:Nginx請(qǐng)求處理流程是怎樣的
網(wǎng)站URL:http://muchs.cn/article22/jpijcc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站策劃、外貿(mào)建站、全網(wǎng)營(yíng)銷(xiāo)推廣、面包屑導(dǎo)航、App設(shè)計(jì)、電子商務(wù)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)