不斷有人跟我說Nginx比Apache好、比Apache快之類。Nginx更主要是做爲反向代理,而非Web服務器使用。我翻譯過一本關於反向代理的技術書籍,同時精通Apache API開發,對Nginx和Apache的工做原理都略有了解,粗談一下見解。數據庫
無論是Nginx仍是Squid這種反向代理,其網絡模式都是事件驅動。事件驅動實際上是很老的技術,早期的select、poll都是如此。後來基於內核通知的更高級事件機制出現,如libevent裏的epoll,使事件驅動性能得以提升。事件驅動的本質仍是IO事件,應用程序在多個IO句柄間快速切換,實現所謂的異步IO。事件驅動服務器,最適合作的就是這種IO密集型工做,如反向代理,它在客戶端與WEB服務器之間起一個數據中轉做用,純粹是IO操做(io操做不會阻塞進程),自身並不涉及到複雜計算。反向代理用事件驅動來作,顯然更好,一個工做進程就能夠run了,沒有進程、線程管理的開銷,CPU、內存消耗都小。編程
因此Nginx、Squid都是這樣作的。固然,Nginx也能夠是多進程 + 事件驅動的模式,幾個進程跑libevent,不須要Apache那樣動輒數百的進程數。Nginx處理靜態文件效果也很好,那是由於靜態文件自己也是磁盤IO操做,處理過程同樣。至於說多少萬的併發鏈接,這個毫無心義。我隨手寫個網絡程序都能處理幾萬的併發,但若是大部分客戶端阻塞在那裏,就沒什麼價值。服務器
再看看Apache或者Resin這類應用服務器,之因此稱他們爲應用服務器,是由於他們真的要跑具體的業務應用,如科學計算、圖形圖像、數據庫讀寫等。它們極可能是CPU密集型的服務,事件驅動並不合適。例如一個計算耗時2秒,那麼這2秒就是徹底阻塞的,什麼event都沒用。想一想MySQL若是改爲事件驅動會怎麼樣,一個大型的join或sort就會阻塞住全部客戶端。這個時候多進程或線程就體現出優點,每一個進程各幹各的事,互不阻塞和干擾。固然,現代CPU愈來愈快,單個計算阻塞的時間可能很小,但只要有阻塞,事件編程就毫無優點。因此進程、線程這類技術,並不會消失,而是與事件機制相輔相成,長期存在。網絡
總結之,事件驅動適合於IO密集型服務,多進程或線程適合於CPU密集型服務,它們各有各的優點,並不存在誰取代誰的傾向。再盲目的言之Nginx能夠取代Apache的,該好好反思了。併發