當整個世界都慢慢傾向于nginx的時候,如果你還在使用apache,那么你可能會用盡一切辦法來保證速度。你也許會調整要加載的模塊,使用Keepalive、擺弄內容協商模塊(mod_negotiation,譯注:從幾個文檔中選擇一個最匹配客戶端要求的文檔)、FollowSymLinks指令(譯注:允許在此目錄中使用軟鏈接)以及重寫功能;你甚至可能還會投入更多硬件,并假裝自己沒有。然而,如果你運營的網站非常繁忙而不想因為內存的原因而導致網站崩潰,那么你就應該關注你所使用的MPM。
MPM,也叫多道處理模塊(Multi Processing Module),關系到真個HTTP會話。從網絡上的監聽、請求進入到最重要的--如何處理子請求,這里我們討論的是子進程及子線程。對于unix系統的機器來說Apache提供了3種MPM以供選擇:; Prefork, Worker, and Event。同時,只對其他系統Apache也提供了許多其他種類的MPM,但是我們這里主要關注最常見的,可能也是你最想看到的(也是我最擅長的)。這些MPM處理Apache服務器用來接受、處理以及服務器HTTP請求過程中的進程和潛在線程。
從不嚴格的角度來看,進程是一個程序的實例。每個進程是完全自包含的,并且在地址空間、變量、內存等方面和其他進程是完全獨立、隔離開來執行的。為了理解本文目的和內容,你可以思考一下下面這句話:5個Apache進程表示運行著5個不同的Apache實例。雖然這是相當值得警告的做法,但是這足以安全的記住本文的目的。
換句話說,一個線程被一個進程創建并擁有。一個進程可以有多個線程,這些線程并不是完全獨立的。它們共享進程為它們分配的同一個狀態以及地址空間。
總之,進程是程序的一個實例,它被用來告訴整個系統它的存在以及需要資源并且可以執行他自己的資源;線程只有被進程創建以后才能真正執行一些東西。因此,線程不需要發布自己而是由整個應用如進程來做,而且線程本質上使用更少的系統資源如內存。
Apache Prefork MPM
Prefork多處理模塊是非線程的。它完全不使用線程,使用整個進程用來處理每個HTTP請求。當一個HTTP請求傳入,假設是用來請求你加貓咪的圖片,那么整個進程都會去該請求捆綁而且為這個人的請求負責。如果在同一時間有其他人來瀏覽你家貓咪的圖片,那么另一個完全不同的進程會被使用。
Prefork在快速和穩定性方面很好。Prefork只有輕微的邊緣響應時間,這是因為它不需要處理在它進程中的不同線程;同時在一個特定的請求發生錯誤的情況下它也是穩定的,因為整個進程只是由一個請求決定,而其他請求是由另外的進程來處理,所以其他請求不受影響。
Prefork也適用于如果你所使用的apache模塊不能處理線程的情況。最常見的是mod_php模塊(盡管它的最新努力方向是ZTS)。你可能在使用PHP以及/或者一些不能被Apache所處理的腳本時會遇到這個問題,但是有一些腳本除外如php-fpm。
但是,如果你需要處理大量的并發請求,這種方式會瘋狂"吃掉"系統資源。請注意,每個進程都會作為一個完整的Apache實例來發布自己。這意味著它會加載所有模塊,而且對每個請求來說都是一個完整的web服務器。如果請求數非常大,而由于協調器需要發布與請求數相同的進程來處理這些請求,這會很快迫使內存使用率達到極限。
Apache Worker MPM
Work多路復用模塊會使用線程,它在高并發時在內存使用方面處理的很好。在多路復用模塊中,需要的進程數較少,因為它不想Prefork那樣需要為每個請求創建一個進程,Worker模式會在進程中創建線程,請求進入的連接通過一個進程中的不同線程來處理。Worker模式中,新的連接只需要等待空閑的線程即可,而不是像Prefork中那樣需要等待空閑進程。
Apache Event MPM
Event模式是非常新的。事實上,它只在Apache2.4版本中被作為穩定版發布。Event模式和Worker模式工作原理相同,它也是使用進程和線程。它們最大的區別在與Event模式會為每個請求創建一個線程,而不是為一個HTTP連接創建一個線程。
新聞熱點
疑難解答