作為老牌伺服器,apache仍在不斷地發展,就目前來說,它一共有三種穩定的mpm(multi-processing module,多程序處理模組)。
它們分別是 prefork、worker 和 event 。
關鍵字:多程序
prefork模式可以算是很古老但是非常穩定的模式。apache在啟動之初,就預派生 fork一些子程序,然後等待請求進來,並且總是檢視保持一些備用的子程序。
之所以這樣做,是為了減少頻繁建立和銷毀程序的開銷。每個子程序中只有乙個執行緒,在乙個時間點內,只能處理乙個請求。
在unix系統中,父程序通常以root身份執行以便邦定80埠,而 apache產生的子程序通常以乙個低特權的使用者執行。
user和group指令用於配置子程序的低特權使用者。執行子程序的使用者必須要對他所服務的內容有讀取的許可權,但是對服務內容之外的其他資源必須擁有盡可能少的許可權。
優點:成熟,相容所有新老模組。程序之間完全獨立,使得它非常穩定。同時,不需要擔心執行緒安全的問題。(我們常用的mod_php,php的拓展不需要支援執行緒安全)
它會將請求放進佇列中,一直等到有可用程序,請求才會被處理。
#伺服器啟動時建立的子程序數量建立的程序數,最多達到每秒32個,直到滿足minspareservers設定的值為止。startservers
5#空閒子程序的最小數量,預設5;如果當前空閒子程序數少於minspareservers ,那麼apache將會產生新的子程序。此引數不要設的太大。
minspareservers
5#空閒子程序的最大數量,預設10;如果當前有超過maxspareservers數量的空閒子程序,那麼父程序會殺死多餘的子程序。此引數也不需要設定太大,如果你將其設定比 minspareservers 小,apache會自動將其修改為minspareservers+1
。 maxspareservers
10#限定伺服器同一時間內客戶端最大接入的請求數量,預設是150;任何超過了該限制的請求都要進入等待佇列,一旦乙個個連線被釋放,佇列中的請求才將得到服務。
maxclients
150#每個子程序在其生命週期內允許最大的請求數量,如果請求總數已經達到這個數值,子程序將會結束,如果設定為0,子程序將永遠不會結束。若該值設定為非0值,可以防止執行php導致的記憶體洩露。
maxrequestsperchild
0
這就是預派生(prefork)的由來。這種模式可以不必在請求到來時再產生新的程序,從而減小了系統開銷以增加效能。
併發量請求數到達maxclients(如256)時,而空閒程序只有10個。apache為繼續增加建立程序。直到程序數到達256個。
當併發量高峰期過去了,併發請求數可能只有乙個時,apache逐漸刪除程序,直到程序數到達maxspareservers為止。
關鍵字:多程序+多執行緒
worker模式比起上乙個,是使用了多程序+多執行緒的模式。
它也預先fork了幾個子程序(數量比較少),每個子程序能夠生成一些服務執行緒和乙個監聽執行緒,該監聽執行緒監聽接入請求並將其傳遞給服務執行緒處理和應答。
apache總是試圖維持乙個備用(spare)或是空閒的服務執行緒池。這樣,客戶端無須等待新執行緒或新程序的建立即可得到處理。
在unix中,為了能夠繫結80埠,父程序一般都是以root身份啟動,隨後,apache以較低許可權的使用者建立子程序和執行緒。
user和group指令用於配置apache子程序的許可權。雖然子程序必須對其提供的內容擁有讀許可權,但應該盡可能給予他較少的特權。
另外,除非使用了suexec ,否則,這些指令配置的許可權將被cgi指令碼所繼承。
執行緒比起程序會更輕量,因為執行緒通常會共享父程序的記憶體空間,因此,記憶體的占用會減少一些,在高併發的場景下,表現得比 prefork模式好。
有些人會覺得奇怪,那麼這裡為什麼不直接使用多執行緒呢(即在乙個程序內實現多程序),還要引入多程序?
原因主要是需要考慮穩定性,如果乙個執行緒異常掛了,會導致父程序連同其他正常的子執行緒都掛了(它們都是同乙個程序下的)。
多程序+多執行緒模式中,各個程序之間都是獨立的,如果某個執行緒出現異常,受影響的只是apache的一部分服務,而不是整個服務。其他程序仍然可以工作。
優點:佔據更少的記憶體,高併發下表現更優秀。
也許中間幾乎沒有請求,這時就會發生阻塞,執行緒被掛起,需要一直等待到超時才會被釋放。
如果過多的執行緒,被這樣佔據,也會導致在高併發場景下的無服務執行緒可用。(該問題在prefork模式下,同樣會發生)
保持連線,會讓某個程序或者執行緒一直處於等待狀態,即使沒有資料過來。
#伺服器啟動時建立的子程序數量理解配置:由主控制程序生成「startservers」個子程序,每個子程序中包含固定的threadsperchild執行緒數,各個執行緒獨立地處理請求。startservers
2#限定伺服器同一時間內客戶端最大接入的請求數量,預設是150;任何超過了該限制的請求都要進入等待佇列,一旦乙個個連線被釋放,佇列中的請求才將得到服務。
maxclients
150#空閒子程序的最小數量
minsparethreads
25#空閒子程序的最大數量
maxsparethreads
75#每個子程序產生的執行緒數量
threadsperchild
25#每個子程序在其生命週期內允許最大的請求數量,如果請求總數已經達到這個數值,子程序將會結束,如果設定為0,子程序將永遠不會結束。將該值設定為非0值,可以防止執行php導致的記憶體洩露。
maxrequestsperchild
0
同樣,為了盡量避免在請求到來才生成執行緒,minsparethreads和maxsparethreads設定了最少和最多的空閒執行緒數;
而maxclients設定了所有子程序中的執行緒總數。如果現有子程序中的執行緒總數不能滿足負載,控制程序將派生新的子程序。
關鍵字:多程序+多執行緒+epoll
這個是 apache中最新的模式,在現在版本裡的已經是穩定可用的模式。
它和 worker模式很像,最大的區別在於,它解決了 keep-alive 場景下 ,長期被占用的執行緒的資源浪費問題
(某些執行緒因為被keep-alive,掛在那裡等待,中間幾乎沒有請求過來,一直等到超時)。
event mpm中,會有乙個專門的執行緒來管理這些 keep-alive 型別的執行緒,當有真實請求過來的時候,將請求傳遞給服務執行緒,
執行完畢後,又允許它釋放。這樣,乙個執行緒就能處理幾個請求了,實現了非同步非阻塞。
event mpm在遇到某些不相容的模組時,會失效,將會回退到worker模式,乙個工作執行緒處理乙個請求。官方自帶的模組,全部是支援event mpm的。
注意一點,event mpm需要linux系統(linux 2.6+)對epoll的支援,才能啟用。
還有,需要補充的是https的連線(ssl),它的執行模式仍然是類似worker的方式,執行緒會被一直占用,知道連線關閉。
部分比較老的資料裡,說event mpm不支援ssl,那個說法是幾年前的說法,現在已經支援了。
#伺服器啟動時建立的子程序數量startservers
3#空閒子程序的最小數量
minsparethreads
75#空閒子程序的最小數量
maxsparethreads
250#每個子程序產生的執行緒數量
threadsperchild
25#限定伺服器同一時間內客戶端最大接入的請求數量,預設是150;任何超過了該限制的請求都要進入等待佇列,一旦乙個個連線被釋放,佇列中的請求才將得到服務。
maxrequestworkers
400#每個子程序在其生命週期內允許最大的請求數量,如果請求總數已經達到這個數值,子程序將會結束,如果設定為0,子程序將永遠不會結束。將該值設定為非0值,可以防止執行php導致的記憶體洩露。
maxrequestsperchild
0
Apache的三種工作模式及相關配置
作為老牌伺服器,apache仍在不斷地發展,就目前來說,它一共有三種穩定的mpm multi processing module,多程序處理模組 它們分別是 prefork worker 和 event 關鍵字 多程序 prefork模式可以算是很古老但是非常穩定的模式。apache在啟動之初,就預...
Apache2 4的三種模式
prefork 多程序模式 乙個主程序,負責生成多個子程序,也稱工作程序,程序之間獨立,每個程序之間只能有乙個執行緒,優點是穩定,缺點是記憶體占用大,每個程序響應乙個使用者請求。worker 多執行緒模式 乙個主程序生多個子程序,每個子程序生成多個執行緒,預設25個,每個執行緒響應乙個使用者請求,優...
VMWare的三種工作模式
1 bridged 橋接模式 這種模式下虛擬系統就相當於區域網中的一台主機,它和宿主機器是完全對等的。需要手動為虛擬系統配置ip位址 子網掩碼,並且要和宿主機器處於同乙個網段,這樣才可以通過區域網的 閘道器或路由器訪問網際網路。2 host only 主機模式 這種模式正如它的名字所示,虛擬系統不能...