nginx是一個被普遍使用的集羣架構組件,咱們有必要對它有足夠的瞭解。下面將先認識nginx:包括應用場景、nginx基本架構、功能特性、併發模型以及配置說明,最後咱們再總結下,爲何選擇nginx的緣由。css
nginx (engine x)是一個能夠做爲HTTP WEB服務器、反向代理服務器、郵件代理服務器和一個通用的TCP / UDP代理服務器(1.9.0版本後)的多功能架構組件,同時也能夠提供必定的緩存服務功能。html
nginx應用比較多的場景是WEB服務器和反向代理服務器,這兩個場景的相關配置後面的文章咱們會分別操做配置,這裏先來認識下:linux
一、WEB服務器:這是應用比較多的場景,配置虛擬主機提供HTTP WEB服務。能夠先經過動態/靜態內容分離,然後爲靜態內容(html/css/js/圖片等)提供HTTP訪問功能;而動態內容能夠整合代理模塊,代理給上游服務器,來支持對外部程序的直接調用或者解析,如FastCGI支持PHP。nginx
二、反向代理服務器:這是應用很是多的場景,爲後端服務器代理。接收客戶端請求,根據負載均衡策略轉發給後端多個上游服務器處理;而後再等待後端服務器返回請求響應,接收到後再返回給請求的客戶端。
web
一、一個master進程生成多個worker子進程(每一個進程只有一個線程),一個worker響應多個用戶請求;後端
二、非阻塞、IO複用、事件驅動:select,poll, epoll, kqueue,/dev/poll;緩存
三、支持sendfile,sendfile64;服務器
四、支持文件AIO(異步I/O);網絡
五、支持mmap;架構
六、靈活的文件配置;
七、佔用內存小:10,000個非活動HTTP保持鏈接佔用大約2.5M內存。
實現與服務靜態文件(靜態資源的web服務器),能緩存打開的文件描述符;
反向代理服務器,緩存、負載均衡、健康狀態檢測;
支持FastCGI;
模塊化機制,非DSO機制,支持多種過濾器gzip,SSI和圖像的模塊完成圖形大小調整等;
支持SSL;
基於名稱和IP作虛擬主機;
支持keeplive;
支持平滑配置更新或程序版本升級;
定製訪問日誌,支持使用日誌緩存以提升性能;
支持URL rewrite;
支持路徑別名;
支持基於IP及用戶的認證;
支持速率限制,併發數限制等;
如前圖,一個master進程生成多個worker子進程(每一個進程只有一個線程),一個worker響應多個用戶請求。若是單進程啓動:僅有一個進程,既充當master進程的角色,也充當worker進程的角色。
4-一、master進程
充當整個進程組與用戶的交互接口(接收來自外界的信號,向各worker進程發送信號),同時監控worker進程的運行狀態。
它不須要處理網絡事件,不負責業務的執行,只會經過管理worker進程來實現重啓服務、平滑升級、更換日誌文件、配置文件實時生效等功能。
4-二、worker進程
主要任務是處理基本的網絡事件,完成具體的任務邏輯。多個worker進程之間是對等的,互相獨立的。
worker進程主要關注點是與客戶端或後端服務器(此時nginx做爲中間代理)之間的數據可讀/可寫等I/O交互事件,因此工做進程的阻塞點是在像select()、epoll_wait()等這樣的I/O多路複用函數調用處,以等待發生數據可讀/寫事件。固然也可能被新收到的進程信號中斷。
worker進程個數:
若是負載以CPU密集型應用爲主,通常會設置與機器cpu核數一致或少一個(用來處理用戶等其餘任務);
若是負載以IO密集型爲主,如響應大量內容給客戶端,則worker數應該爲CPU個數的1.5或2倍。
由於更多的worker數,只會致使進程來競爭cpu資源了,從而帶來沒必要要的上下文切換。並且,nginx爲了更好的利用多核特性,具備cpu綁定選項,咱們能夠將某一個進程綁定在某一個核上,這樣就不會由於進程的切換帶來cache的失效。
更具體的能夠根據公式:Nthread = Ncpu*Ucpu*(1+W/C),Ncpu是cpu的個數,Ucpu是cpu的使用率,W爲等待時間,C爲計算時間。這時須要經過監控工具來獲取相應數據來計算。
最後,再以監控工具數據爲準進行微調。
4-三、併發處理
A、在master進程裏面,先建立socket,並bind、listen在80端口(因此master進程須要root權限);
B、而後再fork出多個worker進程,這樣每一個worker進程均可以去accept這個socket(會產生驚羣問題), 或者使用鎖機制,讓搶到鎖的一個worker進程去accept這個socket,注意這裏通常使用select/poll/epoll機制來解決accept阻塞問題;
C、當一個新鏈接進來後,而只有搶到鎖的一個進程能夠accept這個鏈接進行處理(也是放入epoll中);
D、搶到鎖的worker進程accept到新鏈接後,會當即釋放鎖;而後全部worker進程再次參與搶鎖,這樣就回到了第二步,進行循環處理併發鏈接;
4-四、驚羣問題
A、生產緣由:像上面第二步,多個worker進程等待同一個socket的鏈接事件,當這個事件發生時,這些進程被同時喚醒,就是驚羣。
注意,在linux2.6內核上,accept系統調用已經不存在驚羣,但用epoll機制來解決accept阻塞問題,epoll_wait會有驚羣問題(新增 EPOLLEXCLUSIVE 選項解決了)。
B、致使後果:許多worker進程被內核從新調度喚醒,只有一個進程能夠accept這個鏈接進行處理,其餘餘者皆失敗,致使性能浪費。
C、nginx解決方案:使用鎖機制,讓搶到鎖的一個worker進程去accept(epoll_wait)這個socket;若是操做系統支持原子整型,纔會使用共享內存實現原子上鎖,不然使用文件上鎖。
https://blog.csdn.net/tjiyu/article/details/53027619