Nginx介紹

一、Nginx介紹


Nginx(“engine X”)是一個開源的、支持高併發、高性能的Web服務和反向代理服務軟件。它是由俄羅斯人Lgor Sysoev(伊戈爾·賽索耶夫)開發的,最初應用在俄羅斯大型門戶網站及搜索引擎Rambler上(網址爲www.rambler.ru),後來作者將源代碼以BSD-like協議的形式開源出來以供全球使用。


Nginx最初的設計是用來解決C10k問題的,並在較高負載下對資源的消耗非常小。Nginx正是因爲具有高併發(特別是靜態資源)、對系統資源的消耗非常小等特性而逐漸受到歡迎的。它的二次開發版中較爲有名的有Tengine和OpenResty。


Nginx的官方介紹見 http://nginx.org。



1.1 Nginx的特性


Nginx早期剛開發出來時,其功能特性是較少的,後來功能特性逐漸增加並且完善,很多大型公司也爲之開發了一些功能模塊並開源出來,這都使得Nginx所提供的功能特性越來越強大。以下是Nginx主要的特性:

①模塊化設計,具有較好的擴展性。

②具有高可靠性。

Nginx是基於可靠的Master/Worker兩級架構設計的。

③支持熱部署。

Nginx能夠實現不停機更新配置文件、更換日誌文件、更新服務器程序版本,即實現平滑升級。例如,在升級服務器程序版本時,當重載之後,Nginx過一會兒會在不影響處理用戶請求的情況下慢慢地升級版本,直至完成。

④低內存消耗。

據Nginx官方統計,在10000個keep-alive連接模式下的非活動連接僅消耗2.5M內存。其中非活動連接指的是已經建立的、無數據傳輸的TCP連接。

⑤支持event-driven, aio, mmap機制。



1.2 Nginx的基本功能


①靜態資源的Web服務器。

②http協議的反向代理服務器。

③pop3/imap4協議反向代理服務器。

④支持FastCGI(構建LNMP),uWSGI等協議。

⑤模塊化(非DSO),其中有gzip、ssl等著名模塊。


Nginx主要用於作爲靜態資源的Web服務器http協議的反向代理服務器。當Nginx作爲Web服務器使用時,其能夠提供Web服務器的相關功能,例如虛擬主機、keepalive、訪問日誌、錯誤日誌、url rewrite、路徑別名、基於ip及用戶的訪問控制、基於速率限制及併發數限制等功能。



1.3 Nginx的程序架構


前面提到,Nginx具有高可靠性,因爲其採用了Master/Worker兩級架構來設計。Master/Worker模式是最常用的並行模式之一,其核心思想爲:系統由兩類進程協同工作,即Master進程和Worker進程,其中Master進程負責接收和分配任務,Worker進程負責處理由Master進程分配的小任務,當各個Worker進程將子任務處理完成之後,將處理結果返回給Master進程,由Master進程進行彙總,從而得到最終結果,並返回給Client。其具體處理過程如下。

wKiom1lrdN7hA9rsAABwaBds4NA498.jpg

使用Master/Worker模式的好處,在於它能夠將一個大任務拆分爲多個小任務進行並行執行,從而提高了系統吞吐量。當其中有一個Worker進程將小任務處理完成並將處理結果交給Master進程之後,Master進程會立即這個結果先返回給系統請求者Client,而不會等待系統全部處理完成之後再返回,因此其處理過程是異步的,這樣能使Client發出請求後的等待時間儘可能地降低。


Master/Worker模式中,Master進程是主控進程,它維護了一個Worker進程隊列、Worker進程隊列中的Worker進程、子任務隊列和子結果集,在這個模式中,不斷地從任務隊列中獲取小任務,並將任務處理結果寫入結果集。具體結構如下。

wKiom1lrdVbAuNj0AAIFD6z0uoE054.jpg

注意:在Nginx的Master/Worker兩級架構中,一個Master進程可生成一個或多個Worker進程。其中,Master進程主要負責加載配置文件、管理Worker進程(創建、銷燬)以及平滑升級等,而負責任務處理的Worker進程則可作爲http服務、http代理或者fastcgi代理等。



1.4 Nginx的模塊類型


Nginx的模塊類型有三種,第一種是核心模塊(Core Modules),第二種是標準模塊(Standard Modules),包括了標準HTTP模塊(Standard HTTP Modules)、可選的HTTP模塊(Optional HTTP Modules)和郵件模塊(Mail Modules),第三種是第三方模塊(3rd Party Modules)。



二、Nginx Web服務介紹


Nginx是一個支持高性能、高併發的Web服務軟件,它具備許多優秀的功能特性。作爲Web服務器,它和Apache httpd相比:

①Nginx使用epoll模型,能支持更高的併發連接數,且效率更高。

②Nginx更輕量級,消耗的系統資源更少。


2.1 Nginx與其它Web服務軟件的比較


(1)當處理靜態資源時,Nginx和lighttpd比Apache httpd更據優勢,尤其是在處理靜態小文件(小於1MB)時,其中Nginx優勢更爲明顯。

(2)當處理動態資源時,Apache httpd相對更有優勢一點,但Nginx、lighttpd和Apache httpd三者總體上差距不大。因爲這主要取決於後臺PHP服務器(Java)和數據庫服務器的服務能力,並且與前端的Web靜態服務器和動態服務器的結合方式有一定關係。


構建網站思路:從以上結論可知,Nginx在處理靜態資源時更有優勢,而Apache httpd則在處理動態資源時更有優勢,爲了將二者的優勢結合起來,可以考慮構建LNAMP網站架構。其中,Nginx可以兼作前端調度器和Web靜態資源服務器,但Nginx作爲Web服務器時只負責處理靜態資源而不負責處理動態資源。當收到的動態資源請求時,Nginx將之轉發給後端的Apache httpd,而PHP可作爲Apache httpd的模塊(httpd與php的三種結合方式之一)。這樣一來,這裏的Apache httpd就只負責處理動態資源而不再處理靜態資源了,動態資源請求就交給Apache httpd自帶的PHP引擎處理,需要用到數據時再向數據庫服務器發起請求。這種構建方式既發揮了Nginx處理靜態資源能力高的優勢,也發揮了Apache httpd功能豐富、處理動態資源能力高的優勢。


注意:一般情況先普通PHP引擎的併發連接參考值爲300~1000,Java引擎和數據庫的併發連接參考值爲300~1500。根據業務場景及網站架構的不同,這些參考值也會有上下浮動。



2.2 爲什麼Nginx總體性能比Apache httpd高?


Apache httpd使用的是傳統的select模型(更準確地講,應該是httpd的prefork、worker這兩種MPM模塊使用select模型),而Nginx使用的是較新的epoll(Linux 2.6內核)和kqueue(FreeBSD)模型。其中select模型屬於I/O複用模型(I/O Multiplexing),epoll模型和kqueue模型屬於信號驅動I/O(Signal Driven I/O),也稱事件驅動。相比於Apache httpd,Nginx在處理大量連接的讀寫時,效率更高。


我們知道I/O過程有兩個階段,第一階段是等待數據準備完成階段,即數據先加載至內核內存空間(緩衝區)。第二階段是數據從內核複製到進程階段,即數據從內核空間複製到用戶空間的進程的內存地址空間中去。


對於Apache httpd所採用的select模型而言,當從網絡IO中有請求數據到達時,I/O過程的第一階段就開始了,也就是開始先將數據從網卡加載至內核內存空間,當數據加載到內核空間之後再進行第二階段,即把數據複製到用戶空間中的Apache httpd進程(或線程)的內存空間中去,而究竟是httpd進程還是線程去參與這整個I/O過程取決於httpd採用的MPM模塊(prefork或worker,此處假設httpd採用prefork)。這裏中間有一個問題,就是在I/O過程的第一階段中,負責處理該數據的httpd進程是否要阻塞呢?答案是肯定的,因爲對於I/O複用模型來說,第一階段用戶空間的進程(這裏爲httpd進程)必須阻塞在I/O複用的系統調用上(時刻查看數據已經加載到內核完成了)。一旦第一階段完成,則立即進入第二階段,此時仍然需要阻塞httpd進程,因爲它必須參與將數據複製到自身內存空間中,之後再對其進行處理。總而言之,負責處理該數據的httpd進程在I/O過程的兩個階段都會被阻塞(或被掛起)。如果httpd採用的MPM模塊是worker也同理,負責處理該數據的線程在I/O過程的兩個階段都會阻塞(或被掛起)。


而對於Nginx所採用的epoll模型而言,在I/O過程的第一階段中nginx的進程不需要被阻塞,也不需要盲等,當第一階段完成之後內核通過信號通知機制(callback機制,即回調機制)通知nginx進程,而在第二階段中nginx仍然需要阻塞。


這裏打個比方。例如當你到一個飯館吃飯時,點完菜後就開始等候,假設飯菜做好了需要自己去端口前領取我們知道,一般飯館的服務員看見後臺的師傅做好了一道菜時,會基於廣播或者其他機制通知飯館內的客戶去領取飯菜,這是一種通知方式。而epoll模型就是採用這種通知方式,當你點完菜之後,師傅就開始做菜(數據開始加載至內核空間,即開始執行第一階段),然後你就可以一邊等候一邊做其它事請,例如玩手機,甚至可以利用這個時間空隙到飯館旁邊的商場逛一逛(用戶空間的進程在第一階段不會被阻塞),而當飯菜做好了需要回去吃飯(去執行第二階段),這時飯館前臺服務員可以用廣播通知你,也可以打電話給你並告訴你可以回來領飯吃了(callback機制),而你接到電話之後就回去吃飯(完成第二階段)。因此,epoll模型其實就是信號驅動或者事件驅動的I/O模型。對於那些點的菜已經燒好的客戶,服務員直接一併通知就行了。


但是對於Apache httpd來說就相對麻煩多了。飯館裏的前臺服務員同樣會把飯館內所有客戶點的菜單交給後臺的師傅做,但把每一道菜的完成狀態登記並顯示在飯館內的一個大屏幕上,每個客戶點完菜都必須站在大屏幕前看看自己點的菜做好了沒有。後臺的師傅每燒好一道菜,前臺服務員就更新一次大屏幕(只要大屏幕中有一道菜的完成狀態發生變化就更新整個屏幕。因此,當你點完菜之後,就必須站在大屏幕前,緊緊盯着自己的那道菜的完成狀態,相當於你被阻塞在大屏幕上,而不能做其它事兒(第一階段會被阻塞),一旦完成就馬上去領取(去執行第二階段)。當然,領完飯菜之後就是吃飯了(第二階段也是被阻塞)。需要注意的是,大屏幕上記錄着多道菜的完成狀態(I/O複用),而且每燒好一道菜就需要更新整個屏幕,這就導致了一個問題,隨着點的菜的數量增加,每次更新大屏幕時需要更新狀態的菜的數量線性增加(select的調用複雜度是線性的,即O(n)),因爲每次更新大屏幕時都需要遍歷每一道菜的完成狀態。因此,select模型就是I/O複用模型。另外,當飯館內所有的客戶點完菜之後都必須盯着大屏幕看,直到自己點的菜已經做好了。而大屏幕能夠記錄的菜完成狀態的數量是有限的(select模型支持的併發連接數有限),當然這裏假設大屏幕不能翻轉。而select機制一般最大支持1024路的I/O複用,相當於這裏大屏幕上最多隻能記錄1024道菜的完成狀態。當然,select機制下的最大I/O複用數是可以調大的,但或多或少會影響其處理性能,就好比如大屏幕上本來是最多記錄1024道菜的,爲了記錄更多道菜就只能把屏幕上的字體調小了,但這樣一來對於站在靠後的客戶來說,字體就顯得不是很清楚了。


Apache httpd select和Nginx epoll對比如下表所示

模型

selectepoll

性能

隨着連接數的增加性能急劇下降。處理成千上萬併發連接數時,性能很差隨着連接數的增加,性能基本上沒有下降。處理成千上萬併發連接數時,性能很好
內在處理機制I/O多路複用回調(callback)機制
時間複雜度O(n)O(1)
開發複雜性


I/O過程中用戶空間的進程的狀態

模型selectepoll
I/O過程第一階段阻塞(在I/O多路複用上)非阻塞
I/O過程第二階段阻塞非阻塞


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章