天天看點

Nginx源碼分析—架構設計思想

nginx的源碼可以分為三個部分,一個是在ngx_init_cycle之前,這個也算是為了重新啟動nginx而準備的代碼,比如說在這個時候可以接受外部的信号,也可以儲存傳遞的參數,等等,當然在以後的函數中也考慮了是否正在重新開機nginx。

         至于ngx_init_cycle這個函數,是一個很龐大的函數,在這個函數中可以看到調用了各個子產品的鈎子函數,這裡又設計到了nginx結構體的使用,比如所有的子產品都是ngx_module_t這個結構體,但是這個結構體中的ctx變量和commands type這三個變量使得各個module的功能又有所不同。将每一個子產品都有所歸類

         對于一個标準的HTTP請求中,nginx架構試圖結束完整的HTTP頭部,并在接收到完整的HTPP頭部後将請求分發到具體的HTTP子產品中處理,最常見的即使根據請求的URI(URI在HTTP請求的頭部資訊中)和ngin.conf裡的location配置項的比對度來決定如何分發。

         HTTP子產品間資料流的傳遞,各個子產品之間的寫通過工作,配置檔案中的Location塊決定了比對某種URI的請求将會由相應的HTTP子產品處理,是以,運作時HTTP架構會在接收完畢HTTP請求的頭部後,将請求的URI與配置檔案中的所有location進行比對,比對後再根據Location{}内的配置項選擇HTTP子產品來調用。

         對于ngx_moudle_t結構體中的init_module  init_process 函數指針,前者是在初始化所有子產品時被調用,後者是在worker程序已經産生時被調用,這兩個函數指針之後再ngx_core_event_module子產品中實作了這幾個調用時和nginx架構相關的,對于一個HTTP子產品,NGX_HTTP_MODULE,ngx_module_t中的ctx指向ngx_http_module_t類型的結構體,這個結構體中有8個函數指針,nginx狂a級會在不同的時刻調用這個8個回調來讀取重載配置檔案。

         一個HTTP請求會被許多個配置項控制,實際上這是因為一個HTTP請求可以被許多個HTTP子產品同時處理,這樣就會有一個先手順序問題。由于同一個配置項可以從屬與許多個server location配置快,那麼這個配置項将會針對不同的請求起作用。自己有很大的自由來定義自己的子產品如何介入HTTP請求的處理,

         可以這麼認為,某一個配置項,在不同的層次有不同的作用域,配置項決定了自己感興趣的HTTP請求。

         可以這麼了解配置項,配置項是對某一類HTTP請求感興趣,這個配置項放到某一個配置塊内,當某一類HTTP請求到達後進行比對,根據配置項來判斷有哪些子產品對自己這個HTTP請求感興趣,那麼系統就進行控制對這個HTTP請求調用這個配置項對應的HTTP子產品

         對于一個有參數的配置項,在NGINX中定義了14個常用的類型來辨別配置項中的參數類型,也有對應的參數來處理這些參數。

http{}塊下有一個ngx_http_conf_ctx_t結構,而每一個serve{}塊下也有一個ngx_http_conf_ctx_t結構

         NGINX源碼分析—過濾子產品的意義

         HTTP架構允許普通的HTTP處理子產品介入其中的7個階段處理請求,但是普通大部分HTTP子產品(官方子產品或者第三方子產品)都隻在NGX_HTTP_CONTENT_PHASE階段處理請求,HTTP子產品有兩種介入方法,第一種是,任意一個HTTP子產品會對所有的使用者請求産生作用,第二中方法,隻對請求的URI比對了nginx.conf中某些location表達式下的HTTP子產品起作用,大部分子產品都使用上述的第二種方法處理請求,這種方法的特點是一種請求僅由一個HTTP子產品(在NGX_HTTP_CONTENT_PHASE階段)處理。如果希望多個HTTP子產品共同處理一個請求,則多半是由subrequest功能來完成,即将原始請求分為多個子請求,每個子請求再由一個HTTP子產品在NGX_HTTP_CONTENT_PHASE階段處理。

         對于HTTP過濾子產品則不同,一個請求可以被任意個HTTP過濾子產品處理,是以,普通的HTTP子產品更傾向于完成請求的核心功能,如static子產品複制靜态檔案的處理,HTTP過濾子產品則處理一些附加的功能,如gzip過濾子產品可以把發送給使用者的靜态檔案進行gzip壓縮後在發出去,Image_filter這個第三方過濾子產品可以将圖檔類的靜态檔案制作成縮略圖。而且,這些過濾子產品的效果是可以根據需要疊加的,比如先由Not_modify過濾子產品處理請求中的浏覽器緩存資訊,再交給range過濾子產品處理HTTP range協定(支援斷點續傳),然後交由gzip過濾子產品進行壓縮,一個請求經由各HTTP過濾子產品流水線般地依次進行處理了。

         在普通HTTP子產品處理請求完畢,并調用ngx_http_send_header發送HTTP頭部,或者調用ngx_http_output_filter發送HTTP包體時,才會由這兩個方法依次調用所有的HTTP過濾子產品處理這個請求,是以,HTTP過濾子產品僅處理伺服器發往用戶端的HTTP響應,而不處理用戶端發往伺服器的HTTP請求

         NGINX在進行回應時,分為頭部回應和包體回應,那麼過濾連結清單也分為兩個部分,對于某一個過濾子產品,插入的時候都是插入這個連結清單的首部,是以,HTTP過濾子產品越靠後,在實際執行請求時就越優先執行,以為在初始化HTTP過濾子產品式,每一個HTTP過濾子產品都是将自己插入到整個單連結清單的首部。

繼續閱讀