nginx是一個強大的web server,它支援反向代理,負載均衡,也是很好的靜态檔案伺服器,下面是其多程序模型。
nginx采用多程序模型,單Master多worker,由Master處理外部信号、配置檔案的讀取及worker的初始化,Master不需要處理網絡事件,不負責業務的執行,隻會通過管理worker程序來實作重新開機服務、平滑更新、更換日志檔案、配置檔案實時生效等功能。worker程序采用單線程、非阻塞的事件模型(Event Loop,事件循環)來實作端口的監聽及用戶端請求的處理和響應,同時worker還要處理來自Master的信号。由于worker使用單線程處理各種事件,是以一定要保證主循環是非阻塞的,否則會大大降低worker的響應能力。每個worker程序都是從master程序fork過來,所有worker程序在消息到來時會搶互斥鎖,搶到互斥鎖的那個處理消息,讀取請求,解析請求,處理請求,産生資料後,再傳回給用戶端,最後才斷開連接配接。nginx的每個worker程序都是在epoll或kqueue這樣的事件模型之上,封裝成協程,每個請求都有一個協程進行處理。worker程序的個數是可以設定的,一般我們會設定與機器cpu核數一緻,因為不同的worker程序之間處理并發請求時幾乎沒有同步鎖的限制,是以,當Nginx上的程序數與CPU核心數相等時(最好每一個worker程序都綁定特定的CPU核心),程序間切換的代價是最小的。
當nginx處理一個來自用戶端的請求時,先根據請求頭的host、ip和port來确定由哪個server處理,确定了server之後,再根據請求的uri找到對應的location,這個請求就由這個location處理,更具體一點nginx将一個請求的處理劃分為若幹個不同階段(phase),這些階段按照前後順序依次執行:
NGX_HTTP_POST_READ_PHASE, //0讀取請求phase
NGX_HTTP_SERVER_REWRITE_PHASE,//1這個階段主要是處理全局的(server block)的rewrite
NGX_HTTP_FIND_CONFIG_PHASE, //2這個階段主要是通過uri來查找對應的location,然後根據loc_conf設定r的相應變量
NGX_HTTP_REWRITE_PHASE, //3這個主要處理location的rewrite
NGX_HTTP_POST_REWRITE_PHASE, //4這個主要是進行一些校驗以及收尾工作,以便于交給後面的子產品。
NGX_HTTP_PREACCESS_PHASE, //5比如流控這種access就放在這個phase,也就是說它主要做一些比較粗粒度的access。
NGX_HTTP_ACCESS_PHASE, //6這個比如存取控制,權限驗證就放在這個phase,一般來說處理動作是交給下面的子產品做的.這個主要是做一些細粒度的access
NGX_HTTP_POST_ACCESS_PHASE, //7一般來說當上面的access子產品得到access_code之後就會由這個子產品根據access_code來進行操作
NGX_HTTP_TRY_FILES_PHASE, //8try_file子產品,就是對應配置檔案中的try_files指令,可接收多個路徑作為參數,目前一個路徑的資源無法找到,則自動查找下一個路徑
NGX_HTTP_CONTENT_PHASE, //9内容處理子產品
NGX_HTTP_LOG_PHASE //10log子產品
負載均衡也是Nginx常用的一個功能,而Nginx目前支援自帶3種負載均衡政策,還有2種常用的第三方政策。
1、RR
按照輪詢(預設)方式進行負載,每個請求按時間順序逐一配置設定到不同的後端伺服器,如果後端伺服器down掉,能自動剔除。雖然這種方式簡便、成本低廉。但缺點是:可靠性低和負載配置設定不均衡。
2、權重
指定輪詢幾率,weight和通路比率成正比,用于後端伺服器性能不均的情況。
upstream test{
server localhost:8080 weight=9;
server localhost:8081 weight=1;
}
此時8080和8081分别占90%和10%。
3、ip_hash
上面的2種方式都有一個問題,那就是下一個請求來的時候請求可能分發到另外一個伺服器,當我們的程式不是無狀态的時候(采用了session儲存資料),這時候就有一個很大的很問題了,比如把登入資訊儲存到了session中,那麼跳轉到另外一台伺服器的時候就需要重新登入了,是以很多時候我們需要一個客戶隻通路一個伺服器,那麼就需要用iphash了,iphash的每個請求按通路ip的hash結果配置設定,這樣每個訪客固定通路一個後端伺服器,可以解決session的問題。
upstream test {
ip_hash;
server localhost:8080;
server localhost:8081;
4、fair(第三方)
按後端伺服器的響應時間來配置設定請求,響應時間短的優先配置設定。
upstream backend {
fair;
5、url_hash(第三方)
按通路url的hash結果來配置設定請求,使每個url定向到同一個後端伺服器,後端伺服器為緩存時比較有效。 在upstream中加入hash語句,server語句中不能寫入weight等其他的參數,hash_method是使用的hash算法。
hash $request_uri;
hash_method crc32;
}