Nginx才短短幾年,就拿下了Web服務器大壁江山,眾所周知,Nginx在處理大并發靜態請求方面,效率明顯高于Httpd,甚至能輕松解決C10K問題,
在高并發連接的情況下,Nginx是Apache服務器不錯的替代品,Nginx同時也可以作為7層負載均衡服務器來使用,根據我的測驗結果,Nginx + PHP(FastCGI) 可以承受3萬以上的并發連接數,相當于同等環境下Apache的10倍,
一般來說,4GB記憶體的服務器+Apache(prefork模式)一般只能處理3000個并發連接,因為它們將占用3GB以上的記憶體,還得為系統預留1GB的記憶體,我曾經就有兩臺Apache服務器,因為在組態檔中設定的MaxClients為4000,當Apache并發連接數達到3800時,導致服務器記憶體和Swap空間用滿而崩潰,
而這臺 Nginx + PHP(FastCGI) 服務器在3萬并發連接下,開啟的10個Nginx行程消耗150M記憶體(15M*10=150M),開啟的64個php-cgi行程消耗1280M記憶體(20M*64=1280M),加上系統自身消耗的記憶體,總共消耗不到2GB記憶體,如果服務器記憶體較小,完全可以只開啟25個php-cgi行程,這樣php-cgi消耗的總記憶體數才500M,
在3萬并發連接下,訪問Nginx+ PHP(FastCGI) 服務器的PHP程式,仍然速度飛快,
為什么Nginx在處理高并發方面要優于httpd,我們先從兩種web服務器的作業原理以及作業模式說起,
一、Apache三種作業模式
我們都知道Apache有三種作業模塊,分別為:prefork、worker、event,
- prefork: 多行程,每個請求用一個行程回應,這個程序會用到select機制來通知,
- worker: 多執行緒,一個行程可以生成多個執行緒,每個執行緒回應一個請求,但通知機制還是select不過可以接受更多的請求,
- event: 基于異步I/O模型,一個行程或執行緒,每個行程或執行緒回應多個用戶請求,它是基于事件驅動(也就是epoll機制)實作的,
1、prefork的作業原理
如果不用“–with-mpm”顯式指定某種MPM,prefork就是Unix平臺上預設的MPM,它所采用的預派生子行程方式也是 Apache1.3中采用的模式,
prefork本身并沒有使用到執行緒,2.0版使用它是為了與1.3版保持兼容性;另一方面,prefork用單獨的子行程來處理不同的請求,行程之間是彼此獨立的,這也使其成為最穩定的MPM之一,
2、worker的作業原理
相對于prefork,worker是2.0版中全新的支持多執行緒和多行程混合模型的MPM,由于使用執行緒來處理,所以可以處理相對海量的請求,而系統資源的開銷要小于基于行程的服務器,
但是,worker也使用了多行程,每個行程又生成多個執行緒,以獲得基于行程服務器的穩定性,這種MPM的作業方 式將是Apache2.0的發展趨勢,
3、event 基于事件機制的特性
一個行程回應多個用戶請求,利用callback機制,讓套接字復用,請求過來后行程并不處理請求,而是直接交由其他機制來處理,通過epoll機制來通知請求是否完成;在這個程序中,行程本身一直處于空閑狀態,可以一直接收用戶請求,可以實作一個行程程回應多個用戶請求,支持持海量并發連接數,消耗更少的資源,
二、如何提高Web服務器的并發連接處理能力
有幾個基本條件:
1、基于執行緒,即一個行程生成多個執行緒,每個執行緒回應用戶的每個請求,
2、基于事件的模型,一個行程處理多個請求,并且通過epoll機制來通知用戶請求完成,
3、基于磁盤的AIO(異步I/O)
4、支持mmap記憶體映射,mmap傳統的web服務器,進行頁面輸入時,都是將磁盤的頁面先輸入到內核快取中,再由內核快取中復制一份到web服務器上,mmap機制就是讓內核快取與磁盤進行映射,web服務器,直接復制頁面內容即可,不需要先把磁盤的上的頁面先輸入到內核快取去,
剛好,Nginx 支持以上所有特性,所以Nginx官網上說,Nginx支持50000并發,是有依據的,
三、Nginx優異之處
傳統上基于行程或執行緒模型架構的Web服務通過每行程或每執行緒處理并發連接請求,這勢必會在網路和I/O操作時產生阻塞,其另一個必然結果則是對記憶體或CPU的利用率低下,
生成一個新的行程/執行緒需要事先備好其運行時環境,這包括為其分配堆記憶體和堆疊記憶體,以及為其創建新的執行背景關系等,這些操作都需要占用CPU,而且過多的行程/執行緒還會帶來執行緒抖動或頻繁的背景關系切換,系統性能也會由此進一步下降,
另一種高性能web服務器/Web服務器反向代理:Nginx,Nginx的主要著眼點就是其高性能以及對物理計算資源的高密度利用,因此其采用了不同的架構模型,受啟發于多種作業系統設計中基于“事件”的高級處理機制,Nginx采用了模塊化、事件驅動、異步、單執行緒及非阻塞的架構,并大量采用了多路復用及事件通知機制,
在Nginx中,連接請求由為數不多的幾個僅包含一個執行緒的行程Worker以高效的回環(run-loop)機制進行處理,而每個Worker可以并行處理數千個的并發連接及請求,
四、Nginx 作業原理
Nginx會按需同時運行多個行程:一個主行程(master)和幾個作業行程(worker),配置了快取時還會有快取加載器行程(cache loader)和快取管理器行程(cache manager)等,所有行程均是僅含有一個執行緒,并主要通過“共享記憶體”的機制實作行程間通信,主行程以root用戶身份運行,而worker、cache loader和cache manager均應以非特權用戶身份運行,
在高連接并發的情況下,Nginx是Apache服務器不錯的替代品,
Nginx 安裝非常的簡單 , 組態檔非常簡潔(還能夠支持perl語法),Bugs 非常少的服務器: Nginx 啟動特別容易, 并且幾乎可以做到7*24不間斷運行,即使運行數個月也不需要重新啟動. 你還能夠 不間斷服務的情況下進行軟體版本的升級 ,
五、Nginx 的誕生主要解決C10K問題
最后我們從各自使用的多路復用IO模型來分析:
1、select模型:(apache使用,由于受模塊等限制,用的不多);
單個行程能夠 監視的檔案描述符的數量存在最大限制;
select()所維護的 存盤大量檔案描述符的資料結構 ,隨著檔案描述符數量的增長,其在用戶態和內核的地址空間的復制所引發的開銷也會線性增長;
由于網路回應時間的延遲使得大量TCP連接處于非活躍狀態,但呼叫select()還是會對 所有的socket進行一次線性掃描 ,會造成一定的開銷;
2、poll:poll是unix沿用select自己重新實作了一遍,唯一解決的問題是poll 沒有最大檔案描述符數量的限制;
3、epoll模型:(Nginx使用)
epoll帶來了兩個優勢,大幅度提升了性能:
1)基于事件的就緒通知方式 ,select/poll方式,行程只有在呼叫一定的方法后,內核才會對所有監視的檔案描述符進行掃描,而epoll事件通過epoll_ctl()注冊一個檔案描述符,一旦某個檔案描述符就緒時,內核會采用類似call back的回呼機制,迅速激活這個檔案描述符,epoll_wait()便會得到通知
2)呼叫一次epoll_wait()獲得就緒檔案描述符時,回傳的并不是實際的描述符,而是一個代表就緒描述符數量的值,拿到這些值去epoll指定的一個陣列中依次取得相應數量的檔案描述符即可,這里使用記憶體映射(mmap)技術, 避免了復制大量檔案描述符帶來的開銷
3)當然epoll也有一定的局限性, epoll只有Linux2.6才有實作 ,而其他平臺都沒有,這和apache這種優秀的跨平臺服務器,顯然是有些背道而馳了,
4)簡單來說epoll是select的升級版,單行程管理的檔案描述符沒有最大限制,但epoll只有linux平臺可使用,作為跨平臺的Apache沒有使用
來源:http://codebay.cn/post/8557.html
近期熱文推薦:
1.600+ 道 Java面試題及答案整理(2021最新版)
2.終于靠開源專案弄到 IntelliJ IDEA 激活碼了,真香!
3.阿里 Mock 工具正式開源,干掉市面上所有 Mock 工具!
4.Spring Cloud 2020.0.0 正式發布,全新顛覆性版本!
5.《Java開發手冊(嵩山版)》最新發布,速速下載!
覺得不錯,別忘了隨手點贊+轉發哦!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/264056.html
標籤:Java
上一篇:Spring AOP
下一篇:高頻考點,六大行程通信機制總結
