nginx ("engine x") 是一個高性能的http和 反向代理 伺服器,也是一個 imap/pop3/smtp 伺服器。 nginx 是由 igor sysoev 為俄羅斯通路量第二的 rambler.ru 站點開發的,第一個公開版本0.1.0釋出于2004年10月4日。其将源代碼以類bsd許可證的形式釋出,因它的穩定性、豐富的功能集、示例配置檔案和低系統資源的消耗而聞名。2011年6月1日,nginx 1.0.4釋出。
nginx是一款輕量級的web 伺服器/反向代理伺服器及電子郵件(imap/pop3)代理伺服器,并在一個bsd-like 協定下發行。由俄羅斯的程式設計師igor sysoev所開發,供俄國大型的入口網站及搜尋引擎rambler(俄文:Рамблер)使用。其特點是占有記憶體少,并發能力強,事實上nginx的并發能力确實在同類型的網頁伺服器中表現較好,中國大陸使用nginx網站使用者有:淘寶、百度、新浪、網易、騰訊等。
1、http伺服器。nginx是一個http服務可以獨立提供http服務。可以做網頁靜态伺服器。
2、虛拟主機。可以實作在一台伺服器虛拟出多個網站,例如個人網站使用的虛拟機。
3、反向代理,負載均衡。當網站的通路量達到一定程度後,單台伺服器不能滿足使用者的請求時,需要用多台伺服器叢集可以使用nginx做反向代理。并且堕胎伺服器可以平均分擔負載,不會應為某台伺服器負載高當機而某台伺服器閑置的情況。
nginx七層load balance結構圖:
高并發連接配接: 官方稱單節點支援5萬并發連接配接數,實際生産環境能夠承受2-3萬并發。
記憶體消耗少: 在3萬并發連接配接下,開啟10個nginx程序僅消耗150m記憶體 (15m*10=150m)
配置簡單
成本低廉: 開源免費
支援rewrite重寫規則: 能夠根據域名、url的不同,将http請求分發到後端不同的應用伺服器節點上
内置健康檢查功能: 如果後端的某台應用節點挂了,請求不會再轉發給這個節點,不影響線上功能
節省帶寬: 支援gzip壓縮
反向代理: 支援分布式部署環境,消除單點故障,支援7 * 24小時不停機釋出
阻塞(blocking)
非阻塞(nonblocking )
同步(synchronous )
阻塞i/o(blocking i/o)i/o多路複用
非阻塞i/o(nonblocking i/o)信号驅動
異步(asynchronous )
異步i/o
i/o涉及的對象:
應用程式程序(簡稱程序)
作業系統核心(簡稱核心)
i/o經曆的過程(以讀操作為例):
等待資料準備(簡稱準備過程)
将資料從核心拷貝到程序(簡稱拷貝過程)
阻塞:程序在準備過程中阻塞地等待
非阻塞:程序在準備過程中不會阻塞
同步:程序在拷貝過程中需要阻塞等待
異步:程序在拷貝過程中不需要阻塞等待
最常見也是預設情況下我們會使用的,程序發起read操作後,程序阻塞等待資料準備就緒,程序阻塞等待核心将資料拷貝到程序中。
所謂的select、epoll,又叫事件驅動i/o。在java中叫nio,程序發起一個或多個socket的read請求後:用select/epoll方法阻塞等待資料就緒,一旦有至少一個就緒,程序阻塞等待核心拷貝資料到程序中。處理單個連接配接并不比阻塞i/o快。好處在于可以提高并發性,一個線程可同時處理多個連接配接。
程序發起read操作後
程序無需阻塞等待資料準備就緒,若未就緒立即傳回err
程序過一段時間後再次發起read操作,詢問是否準備就緒
若已經準備就緒,則程序阻塞等待核心将資料拷貝到程序中
程序發起read操作時,注冊信号handler
程序無需阻塞等待資料準備就緒
資料就緒後核心通過信号通知程序,并調用程序注冊的信号handler
程序阻塞等待資料拷貝
程序發起read操作,将socket和接收資料的buffer傳遞給核心後:
無需阻塞等待資料準備就緒
資料就緒後也無需阻塞等待核心拷貝資料
核心拷貝資料完成後發送信号通知程序資料已經可用
nginx使用epoll(linux2.6核心)和kqueue(freebsd)網絡模型,而apache使用傳統的select模型
epoll 與 select都是 i/o 多路複用
epoll是目前在linux下開發大規模并發網絡程式的熱門選擇。
select模型的缺點
最大并發數限制,因為一個程序所打開的fd(檔案描述符)是有限制的,由fd_setsize設定,預設值是1024/2048,是以select模型的最大并發數就被相應限制了。自己改改這個fd_setsize?想法雖好,可是先看看下面吧…
效率問題,select每次調用都會線性掃描全部的fd集合,這樣效率就會呈現線性下降,把fd_setsize改大的後果就是,大家都慢慢來,什麼?都逾時了。
核心/使用者空間 記憶體拷貝問題,如何讓核心把fd消息通知給使用者空間呢?在這個問題上select采取了記憶體拷貝方法。
注:從上面看,select和epoll都需要在傳回後,通過周遊檔案描述符來擷取就緒的socket。事實上,同時連接配接的大量用戶端在同一時刻隻有很少處于就緒狀态,是以随着監視的檔案數量增長,其效率也會呈現線性下降。
epoll 模型的優點:
相對于select和poll來說,epoll更加靈活,沒有描述符限制(它所支援的fd上限是最大可以打開檔案的數目,這個數字一般遠大于2048,舉個例子,在1gb記憶體的機器上大約是10萬左右,具體數目可以cat/proc/sys/fs/file-max察看)。epoll使用一個檔案描述符管理多個描述符,将使用者關系的檔案描述符的事件存放到核心的一個事件表中,這樣在使用者空間和核心空間的copy隻需一次。
io的效率不會随着監視fd的數量的增長而下降。epoll不同于select和poll輪詢的方式,而是通過每個fd定義的回調函數來實作的。隻有就緒的fd才會執行回調函數。
記憶體拷貝,epoll在這點上使用了“共享記憶體”,這個記憶體拷貝也省略了。
注:epoll不僅會告訴應用程式有i/o事件到來,還會告訴應用程式相關的資訊,根據這些資訊應用程式就能直接定位到事件,而不必周遊整個fd集合