更新時間:2021-12-17 12:07:43 來源:動力節點 瀏覽1545次
nginx的內部結構是由核心部分和一系列的功能模塊所組成。這樣劃分是為了使得每個模塊的功能相對簡單,便于開發,同時也便于對系統進行功能擴展。為了便于描述,下文中我們將使用nginx core來稱呼nginx的核心功能部分。
nginx提供了web服務器的基礎功能,同時提供了web服務反向代理,email服務反向代理功能。nginx core實現了底層的通訊協議,為其他模塊和nginx進程構建了基本的運行時環境,并且構建了其他各模塊的協作基礎。除此之外,或者說大部分與協議相關的,或者應用相關的功能都是在這些模塊中所實現的。
nginx將各功能模塊組織成一條鏈,當有請求到達的時候,請求依次經過這條鏈上的部分或者全部模塊,進行處理。每個模塊實現特定的功能。例如,實現對請求解壓縮的模塊,實現SSI的模塊,實現與上游服務器進行通訊的模塊,實現與FastCGI服務進行通訊的模塊。
有兩個模塊比較特殊,他們居于nginx core和各功能模塊的中間。這兩個模塊就是http模塊和mail模塊。這2個模塊在nginx core之上實現了另外一層抽象,處理與HTTP協議和email相關協議(SMTP/POP3/IMAP)有關的事件,并且確保這些事件能被以正確的順序調用其他的一些功能模塊。
目前HTTP協議是被實現在http模塊中的,但是有可能將來被剝離到一個單獨的模塊中,以擴展nginx支持SPDY協議。
nginx的模塊根據其功能基本上可以分為以下幾種類型:
event module:搭建了獨立于操作系統的事件處理機制的框架,及提供了各具體事件的處理。包括ngx_events_module, ngx_event_core_module和ngx_epoll_module等。nginx具體使用何種事件處理模塊,這依賴于具體的操作系統和編譯選項。
phase handler:此類型的模塊也被直接稱為handler模塊。主要負責處理客戶端請求并產生待響應內容,比如ngx_http_static_module模塊,負責客戶端的靜態頁面請求處理并將對應的磁盤文件準備為響應內容輸出。
output filter:也稱為filter模塊,主要是負責對輸出的內容進行處理,可以對輸出進行修改。例如,可以實現對輸出的所有html頁面增加預定義的footbar一類的工作,或者對輸出的圖片的URL進行替換之類的工作。
upstream:upstream模塊實現反向代理的功能,將真正的請求轉發到后端服務器上,并從后端服務器上讀取響應,發回客戶端。upstream模塊是一種特殊的handler,只不過響應內容不是真正由自己產生的,而是從后端服務器上讀取的。
load-balancer:負載均衡模塊,實現特定的算法,在眾多的后端服務器中,選擇一個服務器出來作為某個請求的轉發服務器。
nginx使用一個多進程模型來對外提供服務,其中一個master進程,多個worker進程。master進程負責管理nginx本身和其他worker進程。
所有實際上的業務處理邏輯都在worker進程。worker進程中有一個函數,執行無限循環,不斷處理收到的來自客戶端的請求,并進行處理,直到整個nginx服務被停止。
worker進程中,ngx_worker_process_cycle()函數就是這個無限循環的處理函數。在這個函數中,一個請求的簡單處理流程如下:
操作系統提供的機制(例如epoll, kqueue等)產生相關的事件。
接收和處理這些事件,如是接受到數據,則產生更高層的request對象。
處理request的header和body。
產生響應,并發送回客戶端。
完成request的處理。
重新初始化定時器及其他事件。
為了讓大家更好的了解nginx中請求處理過程,我們以HTTP Request為例,來做一下詳細地說明。
從nginx的內部來看,一個HTTP Request的處理過程涉及到以下幾個階段。
初始化HTTP Request(讀取來自客戶端的數據,生成HTTP Request對象,該對象含有該請求所有的信息)。
處理請求頭。
處理請求體。
如果有的話,調用與此請求(URL或者Location)關聯的handler。
依次調用各phase handler進行處理。
在這里,我們需要了解一下phase handler這個概念。phase字面的意思,就是階段。所以phase handlers也就好理解了,就是包含若干個處理階段的一些handler。
在每一個階段,包含有若干個handler,再處理到某個階段的時候,依次調用該階段的handler對HTTP Request進行處理。
通常情況下,一個phase handler對這個request進行處理,并產生一些輸出。通常phase handler是與定義在配置文件中的某個location相關聯的。
一個phase handler通常執行以下幾項任務:
獲取location配置。
產生適當的響應。
發送response header。
發送response body。
當nginx讀取到一個HTTP Request的header的時候,nginx首先查找與這個請求關聯的虛擬主機的配置。如果找到了這個虛擬主機的配置,那么通常情況下,這個HTTP Request將會經過以下幾個階段的處理(phase handlers):
NGX_HTTP_POST_READ_PHASE:
讀取請求內容階段
NGX_HTTP_SERVER_REWRITE_PHASE:
Server請求地址重寫階段
NGX_HTTP_FIND_CONFIG_PHASE:
配置查找階段:
NGX_HTTP_REWRITE_PHASE:
Location請求地址重寫階段
NGX_HTTP_POST_REWRITE_PHASE:
請求地址重寫提交階段
NGX_HTTP_PREACCESS_PHASE:
訪問權限檢查準備階段
NGX_HTTP_ACCESS_PHASE:
訪問權限檢查階段
NGX_HTTP_POST_ACCESS_PHASE:
訪問權限檢查提交階段
NGX_HTTP_TRY_FILES_PHASE:
配置項try_files處理階段
NGX_HTTP_CONTENT_PHASE:
內容產生階段
NGX_HTTP_LOG_PHASE:
日志模塊處理階段
在內容產生階段,為了給一個request產生正確的響應,nginx必須把這個request交給一個合適的content handler去處理。如果這個request對應的location在配置文件中被明確指定了一個content handler,那么nginx就可以通過對location的匹配,直接找到這個對應的handler,并把這個request交給這個content handler去處理。這樣的配置指令包括像,perl,flv,proxy_pass,mp4等。
如果一個request對應的location并沒有直接有配置的content handler,那么nginx依次嘗試:
如果一個location里面有配置 random_index on,那么隨機選擇一個文件,發送給客戶端。
如果一個location里面有配置 index指令,那么發送index指令指明的文件,給客戶端。
如果一個location里面有配置 autoindex on,那么就發送請求地址對應的服務端路徑下的文件列表給客戶端。
如果這個request對應的location上有設置gzip_static on,那么就查找是否有對應的.gz文件存在,有的話,就發送這個給客戶端(客戶端支持gzip的情況下)。
請求的URI如果對應一個靜態文件,static module就發送靜態文件的內容到客戶端。
內容產生階段完成以后,生成的輸出會被傳遞到filter模塊去進行處理。filter模塊也是與location相關的。所有的fiter模塊都被組織成一條鏈。輸出會依次穿越所有的filter,直到有一個filter模塊的返回值表明已經處理完成。
這里列舉幾個常見的filter模塊,例如:
server-side includes。
XSLT filtering。
圖像縮放之類的。
gzip壓縮。
在所有的filter中,有幾個filter模塊需要關注一下。按照調用的順序依次說明如下:
write:寫輸出到客戶端,實際上是寫到連接對應的socket上。
postpone:這個filter是負責subrequest的,也就是子請求的。
copy:將一些需要復制的buf(文件或者內存)重新復制一份然后交給剩余的body filter處理。
以上就是關于“Nginx模塊化概述”的介紹,大家如果想了解更多相關知識,不妨來關注一下動力節點的Java視頻教程,里面的內容通俗易懂,適合沒有基礎的小伙伴學習,希望對大家能夠有所幫助。
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習