Nginx是使用異步事件驅動的網頁服務器,也可用做反向代理,負載均衡器和http緩存。相比Apache具備佔用內存少、穩定性高的優勢。php
在搭建一個web服務中,nginx所處的位置是在server的最前端,其接受http鏈接、進行gzip壓縮、管理tsl、管理緩存。基本上全部與業務無關而與http服務自己有關的工做都在Nginx身上。前端
沒有接觸過php等語言,而是一開始就從nodejs入手接觸服務端開發的同窗可能並不清楚nginx的定位,由於nodejs自己自帶http模塊,並不必定須要nginx配合。而以php舉例則更爲明白,每一個php文件都是一個接口的入口,其中書寫業務邏輯、鏈接數據庫等,而什麼樣的路徑指派給哪一個php文件是nginx作的工做。node
可是即便在使用nodejs或者tomcat等工具時,仍是會有不少企業級應用會在最前端配上nginx,用來作負載均衡、緩存、反向代理靜態文件等工做。linux
上圖是stackoverflow上的一個插圖,經過ab工具測試靜態文件讀取的性能。即便配置了nodejs cluster,仍是抵不過nginx。nginx
nginx因爲使用了epoll模型(linux 下的一個I/O多路複用模型),要求linux內核版本必須在2.6以上。其默認配置文件在/usr/local/nginx/conf
中。 web
baseconfig:進程數、日誌位置等基本信息
events:採用epoll事件模型,若是linux版本低會下降爲select模型
http:設置超時、壓縮等信息,引入各類模塊
upstream:設置反向代理
server:一個服務,對應一個端口
server
location:一個url,指派到不一樣的cgi或者反向代理
location
複製代碼
在nginx配置中,負載均衡是經過upstream模塊,反向代理是經過proxy_pass實現。redis
http {
upstream firstdemo {
server 39.106.145.33;
server 47.93.6.93;
}
server {
listen 8080;
location / {
proxy_pass http://firstdemo;
}
}
}
複製代碼
如此一來,全部從8080端口的根目錄下的請求都被均衡的轉發到兩個具體的server上。可是這裏的均衡並不是等分,nginx會考慮到連接數量、資源使用等。數據庫
可是負載均衡存在一個問題,就是登錄態的保存。正常狀況下登錄態是保存在每一個server內部,但每一個用戶請求均可能被髮送到任意一個server,剛纔server A上進行了登錄結果到了server B上又沒了權限。對於這個問題,大體有兩類解決方案:一是經過各類hash將同一個用戶的請求發送到同一個server上,好比經過用戶ip判斷;另外一種是將登錄態從server中提出來,保存在公共的如redis這種內存數據庫中。apache
對於nginx,在upstream中設置ip_hash就能夠了。編程
nginx與apache等相比,最主要的特色有三個:
前兩個暫且不談,異步驅動指什麼呢?
在老版本(pre-worker模型)的apache中,每個新的鏈接都要對應一個進程,而新建一個進程的消耗顯然很大。nginx使用epoll(BSD下則是類似的kqueue)模型,一個進程對應多個鏈接。
IO多路複用指經過一種機制,能夠監視多個描述符,一旦某個描述符就緒(通常是讀就緒或者寫就緒),可以通知程序進行相應的讀寫操做。 linux下有三種IO多路複用模型:select、poll、epoll。
簡單點理解,select與poll都是輪詢socket獲取狀態,而epoll是基於回調,性能天然要好一些。
通用網關接口(CGI)可讓一個客戶端從瀏覽器向服務器上的程序請求數據,CGI描述了服務器和請求處理程序之間傳輸數據的一種標準。
CGI的工做方式,從Web服務器的角度看,是在特定的位置定義了能夠運行CGI程序。當收到一個匹配URL的請求,相應的程序就會被調用,並將客戶端發送的數據做爲輸入。程序的輸出會由Web服務器收集,並加上合適的檔頭,再發送回客戶端。
CGI程序運行在獨立的進程中,並對每一個Web請求建立一個進程,這種方法很是容易實現,但效率不好,難以擴展。面對大量請求,進程的大量建立和消亡使操做系統性能大大降低。此外,因爲地址空間沒法共享,也限制了資源重用。
CGI的工做方式大體能夠描述爲:
與CGI「fork-and-execute」的工做模式不一樣,FastCGI像是一個常駐型的CGI,它使用持續的進程來處理一連串的請求。這些進程由FastCGI進程管理器管理,而不是Web服務器。當進來一個請求時,Web服務器把環境變量和這個頁面請求經過一個unix domain socket(好比FastCGI進程與Web服務器都位於本地)或者一個TCP鏈接(FastCGI進程部署在遠端)傳遞給FastCGI進程。
FastCGI實際上就是一個master/worker模型。
FastCGI的工做方式大體能夠描述爲:
nodejs是單線程的,爲了應對高併發的狀況,其經過包裝child_process引入了cluster模塊,其本質上就是master/worker模型,一個主master進程fork若干個worker進程,以充分利用多核cpu。在高版本的nodejs中已經引入了多線程,有興趣的同窗能夠看看。
通常nodejs服務並不經過cluster實現集羣,而是藉助pm2等相似工具,pm2能夠啓動多個實例,由pm2來進行負載均衡,進程守護、平滑重啓等工做。
以上是在網絡編程中經常使用的表示本機地址的三種方式,其區別到底在哪裏?
localhost是127.0.0.1的一個綁定,在linux中其默認地被寫入系統的hosts文件,與127.0.0.1沒什麼區別。固然你能夠手動修改hosts文件。
127.0.0.1是一個虛擬地址,通過本地的lo迴環,走的是這個虛擬網卡,不須要聯網,沒有真實地進行網絡傳輸。
0.0.0.0是本地全部網卡地址的統一,若是本地有多張網卡好比無線網卡和有線網卡,他們各自都會有本身的ip地址,0.0.0.0是他們的統一。
各個網卡的IP,在0.0.0.0中已經說到了。
對nodejs進行接口壓力測試可使用autoconn。