從本節開始,我們將進入http模塊實現原理的講解,關于http模塊,有一個非常重要的點就是其是如何存儲http塊、server塊和location塊的數據的,而且nginx有的配置項是可以在多個配置塊中使用的,當http塊、server塊和location塊中兩個或者兩個以上的配置塊都配置了該配置項的時候,就會有一個問題是,nginx是如何處理這些配置項的。本文主要講解http塊中的各個模塊數據的存儲方式,這將是理解nginx的http模塊的工作方式的重要基石。 1. 核心模塊的存儲方式 在nginx運行過程中,有一個全局配置結構體ngx_cycle_t,其有一個屬性conf_ctx,這個屬性是存儲nginx所有模塊配置的一個數組,這個數組的長度與nginx模塊的個數相同。不過需要注意的是,conf_ctx數組的第一維只會存儲核心模塊的配置,而其他模塊對應的位置處的數組元素其實是為NULL。在conf_ctx中,各個核心模塊配置結構體的存儲位置與該模塊在所有模塊(包括非核心模塊)中的相對位置是一致的,如下圖所示為nginx存儲核心模塊的一個結構示意圖: 這里標注的events和http只是為了展示方便而添加的,本質上這個數組的元素的類型是void*的指針,至于該指針指向的具體結構體的類型,則是根據各個核心模塊自身的定義來的。 在http模塊下,其指向了一個ngx_http_conf_ctx_t類型的結構體,這個結構體的作用就是用來存儲http配置塊中各個配置項的數據的。如下是這個結構體的定義: typedef struct { // 存儲MAIN級別配置 void **main_conf; // 存儲SRV級別配置 void **srv_conf; // 存儲LOC級別配置 void **loc_conf; } ngx_http_conf_ctx_t; 我們知道,在nginx.conf配置文件中,在http塊下還配置有server塊,而server塊下也是可以有location塊,更有甚者,在location塊下可以有子location塊,如此往復,而這里的ngx_http_conf_ctx_t結構體的作用就是存儲所有的這些配置所對應的結構體數據。首先,我們需要明確的一點是,在nginx.conf配置文件中,配置項都是由一個個模塊定義的,一個模塊可以定義多個配置項,對于這些配置項的解析工作都是由這個模塊所定義的方法進行的。但是,一般的,一個模塊一般都只會定義一個結構體,這個結構體中的各個屬性則對應于該模塊所定義的各個配置項的數據,也就是說,通過各個模塊所定義的方法,其會將其所定義的配置項對應的配置轉換為該模塊所定義的結構體。這里所說的結構體就對應于上面的main_conf、srv_conf和loc_conf中的配置。從上面的定義就可以看出,這三個屬性的類型都是指針類型的數組,而數組的長度就對應于模塊的個數,準確來講,是對應于http模塊的各個。在解析各個http模塊的配置之前,nginx會對各個http模塊在當前類型的模塊(http模塊)中進行相對位置進行標記,每個http模塊的相對位置就對應于上面的三個屬性的數組下標。前面已經講到,每個http模塊都只會有一個配置結構體存儲該模塊所定義的所有配置數據,而這些配置結構體就是存儲在上面的三個數組中的。這樣,我們就能夠理解了,其實上面的結構體的三個屬性,每一個屬性的數組都對應了一個http模塊的配置結構體。 既然這里每個模塊都有一個結構體存儲在數組的對應索引位置,那這里為什么需要三個數組呢?比如說,對于ngx_http_core_module,其相對位置在http模塊是第一個,也就是說main_conf[0]、srv_conf[0]和loc_conf[0]存儲的都是ngx_http_core_module的配置結構體,為什么需要三個結構體。這里我們需要說明的是,對于每個http模塊,其會根據需要將配置項按照可使用范圍劃分為三類:僅用于http塊,可以用于http塊和server塊,以及可以用于http塊、server塊和location塊。每一類配置項都使用的是一個不同的結構體,比如ngx_http_core_module就定義了ngx_http_core_main_conf_t用于存儲僅用于http塊的配置項,定義了 ngx_http_core_srv_conf_t用于存儲用于http塊和server塊的配置項,定義了ngx_http_core_loc_conf_t用于存儲用于http塊、server塊和location塊的配置項。對應于上面的數組就是,main_conf[0]的結構體類型為ngx_http_core_main_conf_t,srv_conf[0]的結構體類型為ngx_http_core_srv_conf_t,loc_conf[0]對應的結構體類型為ngx_http_core_loc_conf_t。說到這里,我們就必須要厘清一個問題了,比如,對于某個配置項,其配置在了http塊中,但是其類型是可以用于http塊、server塊和location塊的,那么其就會被存儲在loc_conf[0]中,也就是說,上面的一整個結構體,從目前來看,存儲的都是在http塊中解析出來的各個配置項的數據。那么nginx是如何標記一個配置項是這三種類型中的哪一種呢?這主要是通過ngx_command_t結構體來定義的,如下所示為三個典型的配置: { ngx_string("variables_hash_max_size"), NGX_HTTP_MAIN_CONF | NGX_CONF_TAKE1, ngx_conf_set_num_slot, NGX_HTTP_MAIN_CONF_OFFSET, offsetof(ngx_http_core_main_conf_t, variables_hash_max_size), NULL }, { ngx_string("listen"), NGX_HTTP_SRV_CONF | NGX_CONF_1MORE, ngx_http_core_listen, NGX_HTTP_SRV_CONF_OFFSET, 0, NULL }, { ngx_string("root"), NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_HTTP_LIF_CONF | NGX_CONF_TAKE1, ngx_http_core_root, NGX_HTTP_LOC_CONF_OFFSET, 0, NULL }, 這里我們以variables_hash_max_size、listen和root三個指令為例,這三個指令都是ngx_http_core_module模塊定義的配置項,但是它們存儲的位置則是完全不同的。我們需要注意的就是每個指令的第四個屬性的定義:NGX_HTTP_MAIN_CONF_OFFSET 、NGX_HTTP_SRV_CONF_OFFSET 和 NGX_HTTP_LOC_CONF_OFFSET。這三個類型的定義有兩重含義,一個是表示這個配置項是僅用于http塊,還是可以用于http塊和server塊,再或者是可以用于http塊、server塊和location塊;另一重含義是定義了這個配置項在上面講的ngx_http_conf_ctx_t中的偏移量,所謂的偏移量指的就是,在知道 ngx_http_conf_ctx_t結構體對象的指針地址時,通過這里的偏移量就可以計算出當前配置項所存儲的數組。這里我們就需要展示一段代碼,即在ngx_conf_parse()方法中,其主要是用于解析nginx.conf配置文件的,在解析了某個配置項之后,就會在所有的模塊中,找到該配置項的定義,如果找到了配置項,就會嘗試獲取存儲該配置項所對應的結構體,并且會調用該配置項指定的方法進行配置項數據的解析。這里嘗試獲取該配置項所對應的結構體時,就需要用上上面的偏移量。如下是獲取該配置項的方法: // 查找配置對象,NGX_DIRECT_CONF常量單純用來指定配置存儲區的尋址方法,只用于core模塊 if (cmd->type & NGX_DIRECT_CONF) { conf = ((void **) cf->ctx)[cf->cycle->modules[i]->index]; // NGX_MAIN_CONF常量有兩重含義,其一是指定指令的使用上下文是main(其實還是指core模塊), // 其二是指定配置存儲區的尋址方法。 } else if (cmd->type & NGX_MAIN_CONF) { conf = &(((void **) cf->ctx)[cf->cycle->modules[i]->index]); // 除開core模塊,其他類型的模塊都會使用第三種配置尋址方式,也就是根據cmd->conf的值 // 從cf->ctx中取出對應的配置。舉http模塊為例,cf->conf的可選值是NGX_HTTP_MAIN_CONF_OFFSET、 // NGX_HTTP_SRV_CONF_OFFSET、NGX_HTTP_LOC_CONF_OFFSET, // 分別對應“http{}”、“server{}”、“location{}”這三個http配置級別。 // 這個if判斷的作用主要是,cf->ctx的類型是ngx_http_conf_ctx_t,而cmd->conf主要的值可選 // NGX_HTTP_MAIN_CONF_OFFSET、NGX_HTTP_SRV_CONF_OFFSET、NGX_HTTP_LOC_CONF_OFFSET, // 可以看到ngx_http_conf_ctx_t的屬性有main_conf、srv_conf和loc_conf, // 其實這里就是在計算當前的配置對象是存儲在這三個數組中的哪一個數組中,以default_type指令為例, // 其ngx_command_t的配置為: // {ngx_string("default_type"), // NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_CONF_TAKE1, // ngx_conf_set_str_slot, // NGX_HTTP_LOC_CONF_OFFSET, // offsetof(ngx_http_core_loc_conf_t, default_type), // NULL}, // 可以看到,其conf屬性的值為NGX_HTTP_LOC_CONF_OFFSET,則說明其是存儲在loc_conf數組中的, // 而該數組中的元素類型為ngx_http_core_loc_conf_t,因而可以看到,后面ngx_command_t // 中offset屬性的值就指定為了offsetof(ngx_http_core_loc_conf_t, default_type), // 這就是在計算default_type屬性在ngx_http_core_loc_conf_t結構體中的位置。 // 通過下面的if判斷第一步confp = *(void **) ((char *) cf->ctx + cmd->conf);,就可以 // 計算出當前所使用的結構體是在main_conf、srv_conf // 和loc_conf的哪一個數組中,而通過第二步conf = confp[cf->cycle->modules[i]->ctx_index]; // 的計算,就可以計算出該結構體在數組中的具體位置,并且獲取該結構體數據。 // 需要注意的是,這種計算方式只適用于http模塊的配置項獲取,因為只有http模塊的配置結構體是 // ngx_http_conf_ctx_t類型的 } else if (cf->ctx) { confp = *(void **) ((char *) cf->ctx + cmd->conf); if (confp) { conf = confp[cf->cycle->modules[i]->ctx_index]; } } 這里我們需要重點關注最后一個else if分支,這里就表明了http模塊是如何根據配置項的定義來計算該配置項所對應的結構體的存儲位置的。下面的圖就展示了包含有http塊配置的整體結構: 2. server塊的存儲方式 上面我們講到,使用ngx_http_conf_ctx_t結構體就可以存儲所有的http塊中的配置項,那么server塊中的配置項是如何存儲的呢?其主要存儲在 ngx_http_core_module模塊的main_conf中,也即上面的main_conf[0]所對應的ngx_http_core_main_conf_t結構體中,該結構體有一個屬性 servers ,這個屬性的類型為ngx_array_t,也即一個數組。也就是說,在每個http配置塊下,每個server配置塊都對應于servers數組的一個元素,而數組的元素類型與http塊的一致,還是 ngx_http_conf_ctx_t。不過區別在于,由于當前的配置項一定是可用于server塊或者location塊中的,而不是僅僅只能用于http塊中的,因而配置項的類型一定是上面講到的NGX_HTTP_SRV_CONF_OFFSET和NGX_HTTP_LOC_CONF_OFFSET之一,而不可能是NGX_HTTP_MAIN_CONF_OFFSET。因而這里雖然每個server配置塊對應的配置結構體還是ngx_http_conf_ctx_t,但是其main_conf數組是不會有對應的配置項的,而只能從http塊中繼承配置項。既然是繼承,nginx的處理方式是直接將該數組的指針指向http塊對應的ngx_http_conf_ctx_t的main_conf數組。如下所示為兩個server塊配置的示意圖: 這個圖稍微看起來有點復雜,但實際上并不復雜,按照配置塊劃分,上面的ngx_http_conf_ctx_t中存儲的就是http塊的配置,而下面的兩個 ngx_http_conf_ctx_t存儲的就是兩個server塊中的配置,中間的引用過程是通過http塊的ngx_http_core_module模塊對應的ngx_http_core_main_conf_t.servers進行的。需要注意的一點是,上面的server塊的配置中,main_conf指針都是指向的http塊的對應ngx_http_conf_ctx_t的main_conf屬性。 3. location塊的存儲方式 對于location塊的存儲,其存儲結構也還是ngx_http_conf_ctx_t ,并且由于當前配置項在location塊中的,因而其類型一定不會是 NGX_HTTP_MAIN_CONF_OFFSET和NGX_HTTP_SRV_CONF_OFFSET ,也就是說,解析location配置項得到的數據一定是存儲在loc_conf數組中的。因而,與server塊一樣,location塊對應的ngx_http_conf_ctx_t結構體中的main_conf和srv_conf指向的則是當前location所在的http塊的main_conf和所在的server塊的 srv_conf數組。 另外,一個server塊下會有多個location塊,在存儲結構上,這些location塊是以隊列的方式進行組織的,與server塊類似,這個隊列則是存儲在其所在的server塊對應的ngx_http_conf_ctx_t的loc_conf[0]中的。這里的loc_conf[0]的結構體類型為ngx_http_core_loc_conf_s,其有一個ngx_queue_t類型的屬性 locations 就是該location隊列。最后需要注意的是,這里的locations屬性表征的不僅僅只是server塊下的多個location塊,因為在location配置塊下還可以繼續配置多個location塊,如此不斷遞歸下去。這些子location塊的類型其實還是ngx_http_core_loc_conf_s,因而也是可以通過locations屬性進行表征的。如下是加入location配置塊的結構體示意圖: 圖中展示了兩個location并列組織的情形,其main_conf和srv_conf分別指向了http塊的main_conf和當前location塊所在的server塊的srv_conf,并且兩個location塊對應的結構體是以隊列的方式組織在ngx_http_core_loc_conf_t中的。 4. 小結 本文從ngx_cycle_t結構體開始,介紹了http塊的配置項是如何存儲在ngx_cycle_t中的,并且依次介紹了http塊、server塊和location塊的存儲方式,以及相互之間的組織方式。 以上nginx http模塊數據存儲結構小結就是小編為大家收集整理的全部內容了,希望對大家有所幫助。如果您喜歡這篇文章,可以收藏或分享給您的小伙伴們吧!歡迎持續關注我們的后續更新。 |
免責聲明:本站部分文章和圖片均來自用戶投稿和網絡收集,旨在傳播知識,文章和圖片版權歸原作者及原出處所有,僅供學習與參考,請勿用于商業用途,如果損害了您的權利,請聯系我們及時修正或刪除。謝謝!
始終以前瞻性的眼光聚焦站長、創業、互聯網等領域,為您提供最新最全的互聯網資訊,幫助站長轉型升級,為互聯網創業者提供更加優質的創業信息和品牌營銷服務,與站長一起進步!讓互聯網創業者不再孤獨!
掃一掃,關注站長網微信
當我們在共享網絡訪問的時候,可能會遇到提示指定的網絡名不再可用的問題,這可能是由于我們的共享網絡出現了錯誤,也可能是被共享的對象所拒絕了。指定的網絡名 ......
文/曹楊 原標題:誰還看電視? 爸爸戴一副老花鏡,媽媽戴一副近視鏡,一人坐在沙發,一人躺在床上,各自刷著自己關注的博主更新的短視頻。電視也許開著,但只是背景。 這樣的畫面,幾乎成了洛奇家的常 ...
圖片來源于簡書 文/郭開森 楊帆 陸玖財經準備開新欄目了,每周一創始人郭開森和楊帆合體郭德帆,對行業進行一些觀察和評論,第一篇我們仍是打算寫社區團購,這是當下最火的話題。 來過陸玖財經做客的朋友們...
1、首先進入到“百度”軟件中, 2、然后在其中輸入“百度識圖”, 3、之后點擊圖中的“開始使用”按鈕, 4、緊接著點擊右下角的“相冊”功能, 5、在相冊下 ......
一、軟件沖突1、首先確認是否是應用程序沖突導致的。2、查看是否只有特定幾個游戲或應用會導致該問題。3、如果是應用沖突,那么只要卸載這些app就可以解決了。二 ......
電腦端:1、大家可以點擊右邊鏈接進入網頁版的百度網盤,進入之后點擊“去登錄”。https://pan.baidu.com/2、之后正確的輸入賬號密碼進行登錄就好啦。手機端:1 ......
在填寫一些項目申請書中,總是免不了要選擇一些數字,但是在方框中如何插入數字,該怎么辦呢?那么下面就由學習啦小編給大家分享下word在方框里輸入數字的技巧, ......
8月15日消息 上周,有媒體報道前身為百度圖片的“榴蓮”APP含有大量不雅視頻內容被用戶舉報。對此,百度圖片官方進行了回應,百度圖片表示已經對報道中所涉及的“生吃旋風哥”等爭議內容進行了下線處理。 此外,百度...
一、N100對比intel i3 1、N100的跑分達到了147210分,這個數據可以達到i3的七代級別。 2、在跑分上也是超越了大部分的I3七代CPU,不過比I3八代要弱勢一些。 3 ......
WPS Office手機版怎么加橫線?很多用戶還不知道WPS Office手機版怎么加橫線,WPS Office手機版怎么加橫線,WPS Office手機版怎么打橫線,WPS Office手機版怎么弄 ......
迅雷前綴是什么 答:迅雷前綴是(magnet:?xt=urn:btih:)括號里的就是了。 我們只要在這段文字之后輸入后續的內容,就可以創建下載鏈接了。 1、磁力鏈接不基于文 ......
一、內容特權。 1、半價點播。 許多站內視頻都需要付費觀看,而大會員用戶可以直接半價享受; 購買成功后的48h內無限次觀看。有部分的內容是只限在中國大陸內觀 ......
1、首先打開小米運動的“實驗室功能”。 2、接著點擊“門卡模擬”。 3、然后點擊“我知道了”。 4、最后貼近就可以刷卡成功了。...
答:華為P系列: 華為p40,華為p40plus,華為p50,華為p50e,華為p60 華為mate系列: 華為mate40,華為mate50,華為mate50e,華為mate60 華為nova系列: 華為n ......
近期有用戶反映,電腦在更新Windows 11 Insider Preview 25252.1000后,出現了應用和已壓縮的文件點擊毫無反應,拖拽都不行,只能從開始菜單打開的情況,這是怎 ......
可見單元格就是不包括隱藏或者篩選篩選后隱藏起來的單元格區域。方法:篩選或隱藏數據,復制需要粘貼的值,在目標單元格區域左上角的第一個單元格處右擊,選擇【 ......
答:驍龍8+更好。 驍龍7+gen2實際上就是驍龍8+的低配版本。 在一些其他的核心架構方面都是保持一致的,比如說CPU的架構、GPU的架構等等。 驍龍7+和驍龍8+具體 ......
文/黎明 一場針對中國互聯網巨頭的反壟斷風暴正在醞釀,而且這次動真格了。 11月10日,國家市場監管總局發布《關于平臺經濟領域的反壟斷指南(征求意見稿)》,要加大對互聯網巨頭涉嫌壟斷的調查和監管。 ...
win11系統如何釋放掉系統默認保留的存儲空間?一般情況下,Windows會保留一些存儲空間,以便設備獲得良好性能和成功更新。但是當出現系統盤儲存空間不足時,我們會將幾個G的保留空間釋放出來,以解燃眉之急。本期教...
文件被win10系統誤報病毒自動刪除了如何進行恢復?有用戶下載了某些破解軟件卻被Win10系統誤認為是病毒文件而自動刪除,當然系統自帶殺毒軟件其實挺不錯的,就是有時候會誤報,大家遇到這種情況的時候就希望把誤刪的...
win11系統快速跳過聯網創建本地管理賬戶3種方法?現在市面上銷售的品牌筆記本和臺式機基本上都預裝Windows11家庭中文版正版操作系統,聯網后系統會自動激活。當用戶拿到新機器后還需要按照cortana(小娜)的提示一步...
羅技g304dpi燈顏色代表什么:1、藍色:這種情況是正常工作的顯示,如果說是常亮或者閃爍,那都沒有問題這是在正常工作呢。2、紅色:如果說是紅燈閃爍的話那就是 ......
答:在3DMark壓力測試當中,顯卡需要超高97%才能夠算合格,證明顯卡的穩定性是過關的。 1、一般的默認情況下在2500~3000分就算很正常的了。 2、分數越高說明顯卡 ......
1、先打開機頂盒進入主界面,并且使用遙控器打開設置。 2、然后選擇“賬號與安全”,并且進入。 3、最后往下面翻就可以看到“ADB調試”的選項,直接開啟就行了 ......
相信有非常多使用過筆記本的用戶都聽說過獨顯直連這個詞,但很多用戶并不了解獨顯直連是什么,又有什么用處,那么下面就和小編一起來看看什么是獨顯直連和開啟這 ......
答:中高端水平 i513500hx在處理器當中是處于一個中高端的水平。 i513500hx是第十一代酷睿處理器系列的一員,基礎頻率為2.4GHz,表現十分的不錯。 i513500hx介 ......
win11系統開機總是自動登錄OneDrive如何關閉?win11系統開機的時候,會自動啟動OneDrive,不想要啟動,該怎么操作呢?下面我們就來看看詳細的教程。 在OneDrive界面點小齒輪按鈕,下拉菜單中點【設置】。 單擊【...
1、首先確認手機型號是否支持無線充電功能,(可以在品牌官網找到手機信息查看)2、查看充電板的指示燈是否亮起。指示燈不亮檢查充電器、數據線、電源之間連接是 ......
背景 有時候我們需要獲取文件的創建時間。 例如: 我在研究 《xtrabackup 原理圖》的時候,想通過觀察確認 xtrabackup_log 是最早創建 并且是 最晚保存的 ......