Forum Dictionary / PC / Linux 討論版 / Server /

Apache Prefork 和 Worker 模式

New Subject
Random
Previous
Next
|
Apache Prefork 和 Worker 模式

Apache 2.XX 中 prefork.c 模塊和 worker.c 模塊的比較

空閒子進程:是指沒有正在處理請求的子進程。

1、prefork.c 模塊(一個非線程型的、預設的MPM),prefork MPM 使用多個子進程,每個子進程只有一個線程。每個進程在某個確定的時間只能維持一個連接。在大多數平台上,Prefork MPM 在效率上要比 Worker MPM 要高,但是記憶體使用大得多。prefork 的無線程設計在某些情況下將比 worker 更有優勢:它可以使用那些沒有處理好線程安全的第三方模塊,並且對於那些線程調試困難的平台而言,它也更容易調試一些。

<IfModule prefork.c>
ServerLimit  20000
StartServers  5
MinSpareServers  5
MaxSpareServers  10
MaxClients  1000
MaxRequestsPerChild 0
</IfModule>

ServerLimit     2000
// 預設的MaxClient最大是256個線程,如果想設置更大的值,就的加上 ServerLimit 這個參數。20000 是ServerLimit 這個參數的最大值。如果需要更大,則必須編譯 apache 。在此之前都是不需要重新編譯Apache。生效前提:必須放在其他指令的前面。

StartServers  5
// 指定伺服器啟動時建立的子進程數量,prefork 預設為 5。

MinSpareServers  5
// 指定空閒子進程的最小數量,預設為5。如果當前空閒子進程數少於 MinSpareServers ,那麼 Apache 將以最大每秒一個的速度產生新的子進程。此參數不要設的太大。

MaxSpareServers  10
// 設置空閒子進程的最大數量,預設為10。如果當前有超過 MaxSpareServers 數量的空閒子進程,那麼父進程將殺死多餘的子進程。此參數不要設的太大。如果你將該指令的值設置為比 MinSpareServers 小,Apache將會自動將其修改成 "MinSpareServers+1"。

MaxClients  256
// 限定同一時間客戶端最大接入請求的數量(單個進程並發線程數),預設為256。任何超過 MaxClients 限制的請求都將進入等候隊列,一旦一個鏈接被釋放,隊列中的請求將得到服務。要增大這個值,你必須同時增大ServerLimit 。

MaxRequestsPerChild 10000
// 每個子進程在其生存期內允許伺服的最大請求數量,預設為10000.到達MaxRequestsPerChild的限制後,子進程將會結束。如果MaxRequestsPerChild為"0",子進程將永遠不會結束。

將 MaxRequestsPerChild 設置成非零值有兩個好處:
1.可以防止(偶然的)記憶體泄漏無限進行,從而耗盡記憶體。
2.給進程一個有限壽命,從而有助於當伺服器負載減輕的時候減少活動進程的數量。

工作方式:
一個單獨的控制進程 (父進程) 負責產生子進程,這些子進程用於監聽請求並作出應答。Apache總是試圖保持一些備用的 (spare) 或者是空閒的子進程用於迎接即將到來的請求。這樣客戶端就不需要在得到服務前等候子進程的產生。在 Unix 系統中,父進程通常以 root 身份運行以便邦定 80 端口,而 Apache 產生的子進程通常以一個低特權的用戶運行。 User 和 Group 指令用於設置子進程的低特權用戶。運行子進程的用戶必須要對它所服務的內容有讀取的權限,但是對服務內容之外的其他資源必須擁有盡可能少的權限。

2、worker.c 模塊(支持混合的多線程多進程的多路處理模塊),worker MPM 使用多個子進程,每個子進程有多個線程。每個線程在某個確定的時間只能維持一個連接。通常來說,在一個高流量的 HTTP 伺服器上,Worker MPM 是個比較好的選擇,因為 Worker MPM 的記憶體使用比 Prefork MPM 要低得多。但 worker MPM 也由不完善的地方,如果一個線程崩潰,整個進程就會連同其所有線程一起"死掉".由於線程共享記憶體空間,所以一個程序在運行時必須被系統識別為"每個線程都是安全的"。

<IfModule worker.c>
ServerLimit  50
ThreadLimit  200
StartServers  5
MaxClients  5000
MinSpareThreads  25
MaxSpareThreads  500
ThreadsPerChild  100
MaxRequestsPerChild 0
</IfModule>

ServerLimit 16
// 伺服器允許配置的進程數上限。這個指令和 ThreadLimit 結合使用設置了 MaxClients 最大允許配置的數值。任何在重啟期間對這個指令的改變都將被忽略,但對 MaxClients 的修改卻會生效。

ThreadLimit 64
// 每個子進程可配置的線程數上限。這個指令設置了每個子進程可配置的線程數 ThreadsPerChild 上限。任何在重啟期間對這個指令的改變都將被忽略,但對 ThreadsPerChild 的修改卻會生效。預設值是 "64".

StartServers 3
// 伺服器啟動時建立的子進程數,預設值是"3"。

MinSpareThreads 75
//最小空閒線程數,預設值是"75"。這個 MPM 將基於整個伺服器監視空閒線程數。如果伺服器中總的空閒線程數太少,子進程將產生新的空閒線程。

MaxSpareThreads 250
// 設置最大空閒線程數。預設值是"250"。這個MPM將基於整個伺服器監視空閒線程數。如果伺服器中總的空閒線程數太多,子進程將殺死多餘的空閒線程。MaxSpareThreads 的取值範圍是有限制的。Apache 將按照如下限制自動修正你設置的值:worker 要求其大於等於 MinSpareThreads 加上 ThreadsPerChild 的和

MaxClients 400
// 允許同時伺服的最大接入請求數量 (最大線程數量) 。任何超過 MaxClients 限制的請求都將進入等候隊列。預設值是"400",16 (ServerLimit)  乘以 25 (ThreadsPerChild) 的結果。因此要增加 MaxClients 的時候,你必須同時增加 ServerLimit 的值。

ThreadsPerChild 25
// 每個子進程建立的常駐的執行線程數。預設值是 25。子進程在啟動時建立這些線程後就不再建立新的線程了。

MaxRequestsPerChild  0
// 設置每個子進程在其生存期內允許伺服的最大請求數量。到達 MaxRequestsPerChild 的限制後,子進程將會結束。如果 MaxRequestsPerChild 為"0",子進程將永遠不會結束。

將 MaxRequestsPerChild 設置成非零值有兩個好處:
1.可以防止(偶然的)記憶體泄漏無限進行,從而耗盡記憶體。
2.給進程一個有限壽命,從而有助於當伺服器負載減輕的時候減少活動進程的數量。
注意!對於 KeepAlive 鏈接,只有第一個請求會被計數。事實上,它改變了每個子進程限制最大鏈接數量的行為。

工作方式:
每個進程可以擁有的線程數量是固定的。伺服器會根據負載情況增加或減少進程數量。一個單獨的控制進程 (父進程) 負責子進程的建立。每個子進程可以建立 ThreadsPerChild 數量的服務線程和一個監聽線程,該監聽線程監聽接入請求並將其傳遞給服務線程處理和應答。Apache 總是試圖維持一個備用 (spare) 或是空閒的服務線程池。這樣,客戶端無須等待新線程或新進程的建立即可得到處理。在 Unix 中,為了能夠綁定80端口,父進程一般都是以 root 身份啟動,隨後,Apache 以較低權限的用戶建立子進程和線程。User 和 Group 指令用於設置 Apache 子進程的權限。雖然子進程必須對其提供的內容擁有讀權限,但應該盡可能給予它較少的特權。另外,除非使用了 suexec ,否則,這些指令設置的權限將被 CGI 腳本所繼承。


公式:
ThreadLimit >= ThreadsPerChild
MaxClients  <= ServerLimit * ThreadsPerChild  必須是ThreadsPerChild的倍數
MaxSpareThreads >= MinSpareThreads+ThreadsPerChild

硬限制:

ServerLimi 和 ThreadLimit 這兩個指令決定了活動子進程數量和每個子進程中線程數量的硬限制。要想改變這個硬限制必須完全停止伺服器然後再啟動伺服器 (直接重啟是不行的)。

Apache 在編譯 ServerLimit 時內部有一個硬性的限制,你不能超越這個限制。
prefork MPM 最大為 "ServerLimit 200000"
其它 MPM (包括work MPM) 最大為 "ServerLimit 20000"

Apache在 編譯 ThreadLimit 時內部有一個硬性的限制,你不能超越這個限制。
mpm_winnt 是 "ThreadLimit 15000"
其它 MPM (包括work prefork) 為 "ThreadLimit 20000"

注意!使用 ServerLimit 和 ThreadLimit 時要特別當心。如果將 ServerLimit 和 ThreadLimit 設置成一個高出實際需要許多的值,將會有過多的共享記憶體被分配。當設置成超過系統的處理能力,Apache 可能無法啟動,或者系統將變得不穩定。

  • Keywords : 子進程, ServerLimit, ThreadsPerChild, Apache, ThreadLimit, MaxClients, 線程, prefork, 限制, worker, 預設值, 數量, MinSpareServers, 請求, 父進程, 權限, 模塊, 指令, 建立, StartServers
0 0
2009-01-09T07:24:17+0000

魚戀秋波 Neil Y.K. :

選擇 prefork 還是 worker 可以在編譯時使用–with-mpm=MPM 參數指定,默認為 prefork,prefork 採用預派生子進程方式,用單獨的子進程來處理 不同的請求,進程之間彼此獨立。在 make 編譯和 make install 安裝後,使用 httpd -l 來確定當前使用的 MPM 是 prefork.c。查看 httpd-mpm.conf 配置文件,裏面包含如下默認的配置段:
<IfModule prefork.c>
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 150
MaxRequestsPerChild 0
</IfModule>

prefork
控制進程在最初建立「StartServers」個子進程後,為了滿足 MinSpareServers 設置的需要創建一個進程,等待一秒鍾,繼續創建兩個,再等待一秒鍾,繼續創建四個……如此按指數級增加創建的進程數,最多達到每秒 32 個,直到滿足 MinSpareServers 設置的值為止。這種模式可以不必在請求到來時再產生新的進程,從而減小了系統開銷以增加性能。MaxSpareServers 設置了最大的空閒進程數,如果空閒進程數大於這個值,Apache 會自動 kill 掉一些多餘進程。這個值不要設得過大,但如果設的值比 MinSpareServers 小,Apache會自動把其調整為 MinSpareServers+1。
如果站點負載較大,可考慮同時加大 MinSpareServers 和 MaxSpareServers。 MaxRequestsPerChild設置的是每個子進程可處理的請求數。每個子進程在處理了「MaxRequestsPerChild」個請求後將自動銷毀。0 意味著無限,即子進程永不銷毀。雖然缺省設為 0 可以使每個子進程處理更多的請求,但如果設成非零值也有兩點重要的好處:

1、可防止意外的記憶體泄漏。
2、在伺服器負載下降的時侯會自動減少子進程數。

因此,可根據伺服器的負載來調整這個值。MaxClients 是這些指令中最為重要的一個,設定的是 Apache 可以同時處理的請求,是對 Apache 性能影響最大的參數。其預設值 150 是遠遠不夠的,如果請求總數已達到這個值(可通過 ps -ef|grep http|wc -l 來確認),那麼後面的請求就要排隊,直到某個已處理請求完畢。這就是系統資源還剩下很多而HTTP 訪問卻很慢的主要原因。雖然理論上這個值越大,可以處理的請求就越多,但 Apache 默認的限制不能大於256。ServerLimit 指令無須重編譯 Apache 就可以加大 MaxClients。
<IfModule prefork.c>
ServerLimit  10000
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 10000
MaxRequestsPerChild 0
</IfModule>

Worker

相對於 prefork,worker 全新的支持多線程和多進程混合模型的 MPM。由於使用線程來處理,所以可以處理相對海量的請求,而系統資源的開銷要小於基於進程的伺服器。但是,worker 也使用了多進程,每個進程又生成多個線程,以獲得基於進程伺服器的穩定性。在 configure –with-mpm=worker 後,進行 make 編譯、make install 安裝。在預設生成的 httpd-mpm.conf 中有以下默認配置段:

<IfModule worker.c>
StartServers 2
MaxClients 150
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestsPerChild 0
</IfModule>

Worker 由主控制進程生成「StartServers」個子進程,每個子進程中包含固定的 ThreadsPerChild 線程數,各個線程獨立地處理請求。同樣,為了不在請求到來時再生成線程,MinSpareThreads 和 MaxSpareThreads 設置了最少和最多的空閒線程數;而 MaxClients 設置了同時連入的 clients 最大總數。如果現有子進程中的線程總數不能滿足負載,控制進程將派生新的子進程。MinSpareThreads 和 MaxSpareThreads 的最大缺省值分別是 75 和 250 。這兩個參數對 Apache 的性能影響並不大,可以按照實際情況相應調節。

ThreadsPerChild 是 worker MPM 中與性能相關最密切的指令。ThreadsPerChild 的最大缺省值是 64,如果負載較大,64 也是不夠的。這時要顯式使用 ThreadLimit 指令,它的最大缺省值是 20000。Worker 模式下所能同時處理的請求總數是由子進程總數乘以 ThreadsPerChild 值決定的,應該大於等於 MaxClients。如果負載很大,現有的子進程數不能滿足時,控制進程會派生新的子進程。默認最大的子進程總數是16,加大時也需要顯式聲明 ServerLimit(最大值是20000)。需要注意的是,如果顯式聲明了ServerLimit,那麼它乘以 ThreadsPerChild 的值必須大於等於MaxClients,而且 MaxClients 必須是 ThreadsPerChild 的整數倍,否則 Apache將會自動調節到一個相應值。
<IfModule worker.c>
ServerLimit 25
ThreadLimit 200
StartServers 3
MaxClients 2000
MinSpareThreads 50
MaxSpareThreads 200
ThreadsPerChild 100
MaxRequestsPerChild 0
</IfModule>

下面是利用 Apache 自帶的測試工具 ab 對 Server 進行測試的情況 (設定請求的 index 頁面為 6bytes ),cpu% 為 cpu 占用率,mem 為記憶體使用量 (M為單位),RequestsPerSecond 為每秒處理的請求數。

1、Prefor方式
  (ServerLimit,StartServer,MinSpareServers,MaxSpareServers,MaxClients,MaxRequestPerChild)            

-n/-c(ab參數) Cpu% Mem Requestspersecond
(-,5,5,10,150,0)
100000/100 28.8 285 8434
100000/200 29.2 304 8032
100000/500 25.3 323 7348
100000/1000 24.4 330 5886
(10000,5,5,10,500,0)
100000/100 28.7 371 8345
100000/200 27.4 389 7929
100000/500 24.9 417 7229
100000/1000 23.4 437 6676
(10000,5,5,10,1000,0)
100000/100 28.8 408 8517
100000/200 27.0 422 8045
100000/500 24.2 455 7236
100000/1000 22.5 470 6570
(10000,5,5,10,1500,0)
100000/100 29.6 330 8407
100000/200 28.1 349 8014
100000/500 26.4 380 7290
100000/1000 24.0 400 6686

2、Worker方式

(ServerLimt,Threadlimt,Startservers,MaxClients,MinspareThread,MaxspareThread,ThreadperChild,MaxRequestPerChild)
-n/-c(ab參數) cpu% mem RequestsperSecond
(50,500,5,10000,50,200,200,0)
100000/100  18.6 188 6020
100000/200 20.1 195 5892
100000/500 19.8 209 5708
100000/1000 22.2 218 6081
(100,500,5,10000,50,200,100,0)
100000/100  24.5 240 6919
100000/200 23.6 247 6798
100000/500 24.6 254 6827
100000/1000 22.3 271 6114
(200,500,5,10000,50,200,50,0)
100000/100  27.3 301 7781
100000/200 27.4 307 7789
100000/500 26.0 320 7141
100000/1000 21.8 344 6110
相對來說,prefork 方式速度要稍高於 worker,然而它需要的 cpu 和 memory 資源也稍多於 woker。

如何知道當前apache的應用模式

httpd -l  如果有 prefork.c  那就是 prefork 方式,如果是 worker.c 那就是 work 模式。
忙的原因需要你對你網站進行行為分析。一般是分析日志。然後再根據實際情況做判斷。

曾經給個朋友做過優化。當時他的機器每到晚上 LOAD 基本都是幾十。慢的很。我對日志進行了分析。發現有很多爬蟲在訪問動態的頁面同時有很多 IP 在惡意的盜取圖片數據等。導致大量的資源被消耗掉。最後我采取了適當措施。現在 LOAD 基本都在1以下。所以分析訪問行為是很重要的盲目的調整 APACHE 的連接參數意義真的是不大。希望能夠修正大家的一些不正確的想法。
 

0 0
2009-01-09T07:33:57+0000


  • Now, you can post comments by Facebook Account when your Yampiz account was logout or unvariable. whatever, we suggest to post comment by Yampiz Account to get more bounds to join new events of Heyxu
Comment
 
Verify