1. 程式人生 > >nginx和 apache比較

nginx和 apache比較

nginx 相對 apache 的優點:
  • 輕量級,同樣起web 服務,比apache 佔用更少的記憶體及資源
  • 抗併發,nginx 處理請求是非同步非阻塞的,而apache 則是阻塞型的,在高併發下nginx 能保持低資源低消耗高效能
  • 高度模組化的設計,編寫模組相對簡單
  • 社群活躍,各種高效能模組出品迅速啊


apache 相對nginx 的優點:
  • rewrite ,比nginx 的rewrite 強大
  • 模組超多,基本想到的都可以找到
  • 少bug ,nginx 的bug 相對較多
  • 超穩定(不知道原因,希望有朋友賜教)

nginx的高併發得益於epoll模型。

傳統的apache都是對程序(prefork)或者多執行緒(worker

)工作,假如是prefork,Apache會先生成幾個程序,類似程序池,只不過這裡的程序池會隨著請求數目的增加而增加。對於每一個連線Apache都是在一個程序內處理完畢,具體是recv()以及根據URI去進行磁碟IO尋找檔案,還有send()都是阻塞的,阻塞意味著程序就得掛起進入sleep狀態,那麼一旦連線數很多,Apache必然要生成更多的程序來響應請求,一旦程序多了,CPU對於程序的切換就頻繁了,很耗資源和時間,所以就導致Apache效能下降,就是處理不過來那麼多的程序。

nginx採用epoll模型,非同步非阻塞,對於nginx來說,把一個完整的連結請求處理都劃分成了事件,一個一個的事件,比如

accept,recv,send,磁碟IO,每部分都有相應的模組去處理,一個完整的請求可能是由幾百個模組去處理,真正核心的就是事件手機和分發模組,這就是管理所有模組的核心,只有核心模組的排程才能讓對應的模組佔用CPU資源,從而處理請求,例如http請求:首先在事件手機分發木塊註冊感興趣的監聽事件,註冊號以後不阻塞直接返回,接下來就不需要再管了,等待有連結來了核心就會通知,CPU就可以處理其他事情。一旦有請求來,那麼對整個請求分配相應的上下文(其實已經預先分配好),這時候再註冊新的感興趣的事件(read函式),同樣客戶端資料來了核心會自動通知程序可以去讀資料了,讀了資料之後就是解析,解析完後去磁碟找資源(
I/O),一旦I/O完成會通知程序,程序開始給客戶端發回資料send(),這時候也不是阻塞的,呼叫後就等核心發回通知傳送的結果就行。整個下來把一個請求分成了很多個階段,每個階段都很很多模組去註冊,然後處理,都是非同步非阻塞。非同步這裡指的就是做一個事情,不需要等返回結果,做好了會自動通知你。

可以舉一個簡單的例子來說明Apache的工作流程,我們平時去餐廳吃飯。餐廳的工作模式是一個服務員全程服務客戶,流程是這樣,服務員在門口等候客人(listen),客人到了就接待安排的餐桌上(accept),等著客戶點菜(request uri),去廚房叫師傅下單做菜(磁碟I/O),等待廚房做好(read),然後給客人上菜(send),整個下來服務員(程序)很多地方是阻塞的。這樣客人一多(HTTP請求一多),餐廳只能通過叫更多的服務員來服務(fork程序),但是由於餐廳資源是有限的(CPU),一旦服務員太多管理成本很高(CPU上下文切換),這樣就進入一個瓶頸。再來看看Nginx得怎麼處理?餐廳門口掛個門鈴(註冊epoll模型的listen),一旦有客人(HTTP請求)到達,派一個服務員去接待(accept),之後服務員就去忙其他事情了(比如再去接待客人),等這位客人點好餐就叫服務員(資料到了read()),服務員過來拿走選單到廚房(磁碟I/O),服務員又做其他事情去了,等廚房做好了菜也喊服務員(磁碟I/O結束),服務員再給客人上菜(send()),廚房做好一個菜就給客人上一個,中間服務員可以去幹其他事情。整個過程被切分成很多個階段,每個階段都有相應的服務模組。我們想想,這樣一旦客人多了,餐廳也能招待更多的人。