prefork模式:Apache在啟動之初,就預先fork一些子程序,然後等待請求進來。之是以這樣做,是為了減少頻繁建立和銷毀程序的開銷。每個子程序隻有一個線程,在一個時間點内,隻能處理一個請求。
優點:成熟穩定,相容所有新老子產品。同時,不需要擔心線程安全的問題。(我們常用的mod_php,PHP的拓展不需要支援線程安全)
缺點:一個程序占有更多的資源,消耗記憶體。不擅長處理高并發的請求,在這種情況下,将請求放入隊列,直到有可以處理的程序。
Apache的httpd.conf中的配置方式:
<IfModulempm_prefork_module>
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxRequestWorkers 250
MaxConnectionsPerChild 0
</IfModule>
prefork 控制程序在最初建立“StartServers”個子程序後,為了滿足MinSpareServers設定的需要建立一個程序,等待一秒鐘,繼續建立兩個,再等待一秒鐘,繼續建立四個……如此按指數級增加建立的程序數,最多達到每秒32個,直到滿足MinSpareServers設定的值為止。這種模式 可以不必在請求到來時再産生新的程序,進而減小了系統開銷以增加性能。
MaxSpareServers設定了最大的空閑程序數,如果空閑程序數大于這個值,Apache會自動kill掉一些多餘程序。這個值不要設得過大,但如果設的值比MinSpareServers小,Apache會自動把其調整為 MinSpareServers+1。如果站點負載較大,可考慮同時加大MinSpareServers和MaxSpareServers。
MaxRequestsPerChild設定的是每個子程序可處理的請求數。每個子程序在處理了“MaxRequestsPerChild”個請求後将自動銷毀。0意味着無限,即子程序永不銷毀。雖然預設設為0可以使每個子程序處理更多的請求,但如果設成非零值也有兩點重要的好處:
1、可防止意外的記憶體洩漏。2、在伺服器負載下降的時侯會自動減少子程序數。
是以,可根據伺服器的負載來調整這個值。
MaxRequestWorkers指令集同時将服務請求的數量上的限制。任何連接配接嘗試在MaxRequestWorkerslimit将通常被排隊,最多若幹基于上ListenBacklog指令。
在apache2.3.13以前的版本MaxRequestWorkers被稱為MaxClients 。
、
(MaxClients是這些指令中最為重要的一個,設定的是 Apache可以同時處理的請求,是對Apache性能影響最大的參數。其預設值150是遠遠不夠的,如果請求總數已達到這個值(可通過ps -ef|grephttp|wc -l來确認),那麼後面的請求就要排隊,直到某個已處理請求完畢。這就是系統資源還剩下很多而HTTP通路卻很慢的主要原因。雖然理論上這個值越大,可以處理的請求就越多,但Apache預設的限制不能大于256。)
worker模式:是使用了多程序和多線程的混合模式。它也預先fork了幾個子程序(數量比較少),然後每個子程序建立一些線程,同時包括一個監聽線程。每個請求過來,會被配置設定到1個線程來服務。線程比起程序會更輕量,因為線程通常會共享父程序的記憶體空間,是以,記憶體的占用會減少一些。在高并發的場景下,因為比起prefork有更多的可用線程,表現會更優秀一些。
有些人會覺得奇怪,那麼這裡為什麼不完全使用多線程呢,還要引入多程序?
原因主要是需要考慮穩定性,如果一個線程異常挂了,會導緻父程序連同其他正常的子線程都挂了(它們都是同一個程序下的)。為了防止這場異常場景出現,就不能全部使用線程,使用多個程序再加多線程,如果某個線程出現異常,受影響的隻是Apache的一部分服務,而不是整個服務。
優點:占據更少的記憶體,高并發下表現更優秀。
缺點:必須考慮線程安全的問題,因為多個子線程是共享父程序的記憶體位址的。如果使用keep-alive的長連接配接方式,某個線程會一直被占據,也許中間幾乎沒有請求,需要一直等待到逾時才會被釋放。如果過多的線程,被這樣占據,也會導緻在高并發場景下的無服務線程可用。(該問題在prefork模式下,同樣會發生)
注:keep-alive的長連接配接方式,是為了讓下一次的socket通信複用之前建立的連接配接,進而,減少連接配接的建立和銷毀的系統開銷。保持連接配接,會讓某個程序或者線程一直處于等待狀态,即使沒有資料過來。
<IfModulempm_worker_module>
StartServers 3
MinSpareThreads 75
MaxSpareThreads 250
ThreadsPerChild 25
MaxRequestWorkers 400
# StartServers: 初始數量的伺服器程序開始
#MinSpareThreads: 最小數量的工作線程,儲存備用
#MaxSpareThreads: 最大數量的工作線程,儲存備用
#ThreadsPerChild: 固定數量的工作線程在每個伺服器程序
# MaxRequestWorkers: 最大數量的工作線程
#MaxConnectionsPerChild: 最大連接配接數的一個伺服器程序服務
Worker 由主要制程序生成“StartServers”個子程序,每個子程序中包含固定的ThreadsPerChild線程數,各個線程獨立地處理請求。同樣,為了不在請求到來時再生成線程,MinSpareThreads和MaxSpareThreads設定了最少和最多的空閑線程數;
而MaxRequestWorkers設定了同時連入的clients最大總數。如果現有子程序中的線程總數不能滿足負載,控制程序将派生新的子程序
MinSpareThreads和 MaxSpareThreads的最大預設值分别是75和250。這兩個參數對Apache的性能影響并不大,可以按照實際情況相應調節。
ThreadsPerChild是worker MPM中與性能相關最密切的指令。ThreadsPerChild的最大預設值是64,如果負載較大,64也是不夠的。這時要顯式使用 ThreadLimit指令,它的最大預設值是20000。
Worker模式下所能同時處理的請求總數是由子程序總數乘以ThreadsPerChild 值決定的,應該大于等于MaxRequestWorkers。如果負載很大,現有的子程序數不能滿足時,控制程序會派生新的子程序。預設最大的子程序總數是16,加大時 也需要顯式聲明ServerLimit(最大值是20000)。需要注意的是,如果顯式聲明了ServerLimit,那麼它乘以 ThreadsPerChild的值必須大于等于MaxRequestWorkers,而且MaxRequestWorkers必須是ThreadsPerChild的整數倍,否則 Apache将會自動調節到一個相應值。
event MPM 模式:
這個是Apache中最新的模式,在現在版本裡的已經是穩定可用的模式。它和worker模式很像,最大的差別在于,它解決了keep-alive場景下,長期被占用的線程的資源浪費問題(某些線程因為被keep-alive,空挂在哪裡等待,中間幾乎沒有請求過來,甚至等到逾時)。event MPM中,會有一個專門的線程來管理這些keep-alive類型的線程,當有真實請求過來的時候,将請求傳遞給服務線程,執行完畢後,又允許它釋放。這樣增強了高并發場景下的請求處理能力。
本文轉自wsw26 51CTO部落格,原文連結:http://blog.51cto.com/wsw26/1750699,如需轉載請自行聯系原作者