apache性能優化

Apache優化:修改最大併發連接數

Apache是一個跨平臺的web服務器,由於其簡單高效、穩定安全的特性,被廣泛應用於計算機技術的各個領域。現在,Apache憑藉其龐大的用戶數,已成爲用戶數排名第一的web服務器。

管如此,在實際的生產環境中,我們仍然不可能直接使用默認配置的Apache來充當服務器。畢竟,爲了更充分合理地利用Apache服務器,我們都應該根 據自己的實際需要對Apache的默認配置作出一些必要的調整。而針對Apache的優化配置過程中,修改Apache的最大併發連接數就顯得尤爲重要。

在修改Apache的最大併發連接數之前,我們需要預先了解一些Apache的相關知識。

所周知,Apache是一個跨平臺的、採用模塊化設計的服務器。爲了應對不同的平臺和不同的環境產生的各種不同的需求,也爲了在具體的平臺或環境下達到最 佳的效果,Apacheweb服務器的基礎功能方面(端口綁定、接收請求等)也同樣採用了模塊化設計,這個Apache的核心模塊就叫做多路處理模塊 (Multi-Processing Module,簡稱MPM)

Apache針對不同的操作系統提供了多個不同的MPM模塊,例如:mpm_beosmpm_eventmpm_netwarempmt_os2mpm_preforkmpm_winntmpm_worker 如果條件允許,我們可以根據實際需求將指定的MPM模塊編譯進我們自己的Apache(Apache的源碼是開放的,允許用戶自行編譯)。不過,如果在 編譯時我們沒有選擇,Apache將按照如下表格根據不同的操作系統自行選擇對應的MPM模塊,這也是Apache針對不同平臺推薦使用的MPM模塊。

不同操作系統上默認的MPM模塊

操作系統

MPM模塊

描述

Windows

mpm_winnt

不用介紹了吧:)

Unix/Linux

mpm_prefork

不用介紹了吧:)

BeOS

mpm_beos

Be公司開發的一種多媒體操作系統,官方版已停止更新。

Netware

mpm_netware

NOVELL公司推出的一種網絡操作系統

OS/2

mpmt_os2

一種最初由微軟和IBM共同開發的操作系統,現由IBM單獨開發(微軟放棄OS/2,轉而開發Windows)

mpm_event模塊可以看作是mpm_worker模塊的一個變種,不過其具有實驗性質,一般不推薦使用。

當然,Apache在其官方網站上也提供了根據不同操作系統已經編譯好對應MPM模塊的成品Apache。你可以點擊此處進入Apache官方網站下載。

此外,如果我們想要知道某個Apache內部使用的是何種MPM模塊,我們可以以命令行的方式進入Apache安裝目錄\bin,然後鍵入命令httpd -l,即可查看到當前Apache內部使用的何種MPM模塊。

使用httpd -l命令查看編譯模塊

由於在平常的開發工作中,BeOSNetWareOS/2等操作系統並不常見,這裏我們主要針對WindowsUnix/Linux操作系統上的MPM模塊進行講解。在WindowsUnix/Linux操作系統上,MPM模塊主要有mpm_winntmpm_preforkmpm_worker三種。

mpm_prefork模塊

mpm_prefork模塊主要應用於Unix/Linux平臺的Apache服務器,其主要工作方式是:當Apache服務器啓動後,mpm_prefork模塊會預先創建多個子進程(默認爲5),當接收到客戶端的請求後,mpm_prefork模塊再將請求轉交給子進程處理,並且每個子進程同時只能用於處理單個請求。如果當前的請求數將超過預先創建的子進程數時,mpm_prefork模塊就會創建新的子進程來處理額外的請求。Apache總是試圖保持一些備用的或者是空閒的子進程用於迎接即將到來的請求。這樣客戶端的請求就不需要在接收後等候子進程的產生。

由於在mpm_prefork模塊中,每個請求對應一個子進程,因此其佔用的系統資源相對其他兩種模塊而言較多。不過mpm_prefork模塊的優點在於它的每個子進程都會獨立處理對應的單個請求,這樣,如果其中一個請求出現問題就不會影響到其他請求。同時,mpm_prefork模塊可以應用於不具備線程安全的第三方模塊(比如PHP的非線程安全版本),且在不支持線程調試的平臺上易於調試。此外,mpm_prefork模塊還具有比mpm_worker模塊更高的穩定性。

mpm_worker模塊

mpm_worker模塊也主要應用於Unix/Linux平臺的Apache服務器,它可以看作是mpm_prefork模塊的改進版。mpm_worker模塊的工作方式與mpm_prefork模塊類似。不過,由於處理相同請求的情況下,基於進程(例如mpm_prefork)比基於線程的處理方式佔用的系統資源要多。因此,與mpm_prefork模塊不同的是,mpm_worker模塊會讓每個子進程創建固定數量的服務線程和一個監聽線程,並讓每個服務線程來處理客戶端的請求,監聽線程用於監聽接入請求並將其傳遞給服務線程處理和應答。Apache總是試圖維持一個備用或是空閒的服務線程池。這樣,客戶端無須等待新線程或新進程的建立即可得到處理。

mpm_prefork模塊相比,mpm_worker模塊可以進一步減少系統資源的開銷。再加上它也使用了多進程,每個進程又有多個線程,因此它與完全基於線程的處理方式相比,又增加了一定的穩定性。

mpm_winnt模塊

mpm_winnt模塊是專門針對Windows操作系統而優化設計的MPM模塊。它只創建一個單獨的子進程,並在這個子進程中輪流產生多個線程來處理請求。

修改MPM模塊配置

在對ApacheMPM模塊具備一定了解後,我們就可以針對不同的MPM模塊來修改Apache的最大併發連接數配置了。

1.啓用MPM模塊配置文件

Apace安裝目錄/conf/extra目錄中有一個名爲httpd-mpm.conf的配置文件。該文件主要用於進行MPM模塊的相關配置。不過,在默認情況下,ApacheMPM模塊配置文件並沒有啓用。因此,我們需要在httpd.conf文件中啓用該配置文件,如下所示:

# Server-pool management (MPM specific)

Include conf/extra/httpd-mpm.conf (去掉該行前面的註釋符號"#")

2.修改MPM模塊配置文件中的相關配置

在啓動MPM模塊配置文件後,我們就可以使用文本編輯器打開該配置文件,我們可以看到,在該配置文件中有許多<IfModule>配置節點,如下圖所示:

只有Apache使用對應MPM模塊時,對應配置纔會生效

此時,我們就需要根據當前Apache服務器所使用的MPM模塊,來修改對應<IfModule>節點下的參數配置。首先,我們來看看mpm_winnt模塊下的默認配置:

#由於mpm_winnt模塊只會創建1個子進程,因此這裏對單個子進程的參數設置就相當於對整個Apache的參數設置。

 

<IfModule mpm_winnt_module>

ThreadsPerChild      150 #推薦設置:小型網站=1000 中型網站=1000~2000 大型網站=2000~3500

MaxRequestsPerChild    0 #推薦設置:小=10000 中或大=20000~100000

</IfModule>

對應的配置參數作用如下:

ThreadsPerChild

每個子進程的最大併發線程數。

MaxRequestsPerChild

每個子進程允許處理的請求總數。如果累計處理的請求數超過該值,該子進程將會結束(然後根據需要確定是否創建新的子進程),該值設爲0表示不限制請求總數(子進程永不結束)

該參數建議設爲非零的值,可以帶來以下兩個好處:

1. 可以防止程序中可能存在的內存泄漏無限進行下去,從而耗盡內存。

2. 給進程一個有限壽命,從而有助於當服務器負載減輕的時候減少活動進程的數量。

注意:在以上涉及到統計請求數量的參數中,對於KeepAlive的連接,只有第一個請求會被計數。

接着,我們再來看看mpm_perfork模塊和mpm_worker模塊下的默認配置:

#mpm_perfork模塊

 

<IfModule mpm_prefork_module>

StartServers          5 #推薦設置:小=默認 中=20~50 =50~100

MinSpareServers       5 #推薦設置:與StartServers保持一致

MaxSpareServers      10 #推薦設置:小=20 =30~80 =80~120

MaxClients          150 #推薦設置:小=500 =500~1500 大型=1500~3000

MaxRequestsPerChild   0 #推薦設置:小=10000 中或大=10000~500000

(此外,還需額外設置ServerLimit參數,該參數最好與MaxClients的值保持一致。)

</IfModule>

# StartServers:  數量的服務器進程開始

# MinSpareServers:  最小數量的服務器進程,保存備用

# MaxSpareServers:  最大數量的服務器進程,保存備用

# MaxRequestWorkers:  最大數量的服務器進程允許開始

# MaxConnectionsPerChild:  最大連接數的一個服務器進程服務

  prefork 控制進程在最初建立 “StartServers”個子進程後,爲了滿足MinSpareServers設置的需要創建一個進程,等待一秒鐘,繼續創建兩 個,再等待一秒鐘, 繼續創建四個……如此按指數級增加創建的進程數,最多達到每秒32個,直到滿足MinSpareServers設置的值爲止。這種模式 可以不必在請求到 來時再產生新的進程,從而減小了系統開銷以增加性能。MaxSpareServers設置了最大的空閒進程數,如果空閒進程數大於這個 值,Apache 會自動kill掉一些多餘進程。這個值不要設得過大,但如果設的值比MinSpareServers小,Apache會自動把其調整 爲 MinSpareServers+1。如果站點負載較大,可考慮同時加大MinSpareServersMaxSpareServers  

  MaxRequestsPerChild設置的是每個 子進程可處理的請求數。每個子進程在處理了“MaxRequestsPerChild”個請求後將自 動銷燬。0意味着無限,即子進程永不銷燬。雖然缺省 設爲0可以使每個子進程處理更多的請求,但如果設成非零值也有兩點重要的好處:

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

因此,可根據服務器的負載來調整這個值。

  MaxRequestWorkers指令集同時將服務請求的數量上的限制。任何連接嘗試在MaxRequestWorkerslimit將通常被排隊,最多若干基於上ListenBacklog指令。 

apache2.3.13以前的版本MaxRequestWorkers被稱爲MaxClients 

MaxClients是這些指令中最爲重要的一個,設定的是 Apache可以同 時處理的請求,是對Apache性能影響最大的參數。其缺省值150是遠遠不夠的,如果請求總數已達到這個值(可通過 ps -ef|grep http|wc -l來確認),那麼後面的請求就要排隊,直到某個已處理請求完畢。這就是系統資源還剩下很多而HTTP訪問卻很 慢的主要原因。雖然理論上這個值越大,可以 處理的請求就越多,但Apache默認的限制不能大於256。)

 

 

 

#mpm_worker模塊

 

<IfModule mpm_worker_module>

StartServers          2 #推薦設置:小=默認 中=3~5 =5~10

MaxClients          150 #推薦設置:小=500 =500~1500 大型=1500~3000

MinSpareThreads      25 #推薦設置:小=默認 中=50~100 =100~200

MaxSpareThreads      75 #推薦設置:小=默認 中=80~160 =200~400

ThreadsPerChild      25 #推薦設置:小=默認 中=50~100 大型=100~200

MaxRequestsPerChild   0 #推薦設置:小=10000 中或大=10000~50000

(此外,如果MaxClients/ThreadsPerChild大於16,還需額外設置ServerLimit參數,ServerLimit必須大於等於 MaxClients/ThreadsPerChild 的值。)

</IfModule>

對應的配置參數作用如下:

StartServers

啓動Apache時創建的子進程數。

MinSpareServers

處於空閒狀態的最小子進程數。

所謂空閒子進程是指沒有正在處理請求的子進程。如果當前空閒子進程數少於MinSpareServers,那麼Apache將以最大每秒一個的速度產生新的子進程。只有在非常繁忙機器上才需要調整這個參數。此值不宜過大。

MaxSpareServers

處於空閒狀態的最大子進程數。

只有在非常繁忙機器上才需要調整這個參數。此值不宜過大。如果你將該指令的值設置爲比MinSpareServers小,Apache將會自動將其修改成MinSpareServers+1

MaxClients

允許同時連接的最大請求數量。

任何超過MaxClients限制的請求都將進入等待隊列,直到達到ListenBacklog指令限制的最大值爲止。

對於非線程型的MPM(也就是mpm_prefork)MaxClients表示可以用於處理客戶端請求的最大子進程數量,默認值是256。要增大這個值,你必須同時增大ServerLimit

對於線程型或者混合型的MPM(也就是mpm_beosmpm_worker)MaxClients表示可以用於處理客戶端請求的最大線程數量。線程型的mpm_beos的默認值是50。對於混合型的MPM默認值是16(ServerLimit)乘以25(ThreadsPerChild)的結果。因此要將MaxClients增加到超過16個進程才能提供的時候,你必須同時增加ServerLimit的值。

MinSpareThreads

處於空閒狀態的最小線程數。

不同的MPM對這個指令的處理是不一樣的:

mpm_worker的默認值是75。這個MPM將基於整個服務器監視空閒線程數。如果服務器中總的空閒線程數太少,子進程將產生新的空閒線程。mpm_netware的默認值是10。既然這個MPM只運行單獨一個子進程,此MPM當然亦基於整個服務器監視空閒線程數。mpm_beosmpmt_os2的工作方式與mpm_netware差不多,mpm_beos的默認值是1mpmt_os2的默認值是5

MaxSpareThreads

處於空閒狀態的最大線程數。

不同的MPM對這個指令的處理是不一樣的:

mpm_worker的默認值是250。這個MPM將基於整個服務器監視空閒線程數。如果服務器中總的空閒線程數太多,子進程將殺死多餘的空閒線程。mpm_netware的默認值是100。既然這個MPM只運行單獨一個子進程,此MPM當然亦基於整個服務器監視空閒線程數。mpm_beosmpmt_os2的工作方式與mpm_netware差不多,mpm_beos的默認值是50mpmt_os2的默認值是10

備註ServerLimit表示Apache允許創建的最大進程數。 值得注意的是,Apache在編譯時內部有一個硬限制ServerLimit 20000(對於mpm_prefork模塊爲ServerLimit 200000)。你不能超越這個限制。
使用這個指令時要特別當心。如果將ServerLimit設置成一個高出實際需要許多的值,將會有過多的共享內存被分配。如果將ServerLimitMaxClients設置成超過系統的處理能力,Apache可能無法啓動,或者系統將變得不穩定。

注意:在配置相關參數時,請先保證服務器具備足夠的硬件性能(例如:CPU、內存等)。 如果發現自啓動後,隨着服務器的運行時間增加,服務器的內存佔用也隨之增加,可能是程序中出現內存泄露,請向下調整參數MaxRequestsPerChild的值以降低內存泄露帶來的影響,然後儘快找出程序中的問題之所在。

 

案例:apache的最大併發數配置成1000 
1.首先確認apachempm方式 
cmd>httpd.exe -l 可以看到是什麼模式了 
這裏就看mpm_xxx.c這個xxx就是那個了

2.修改httpd.conf文件 
搜索mpm,找到 Server-pool management(MPM specific) 
去掉# Include conf/extra/httpd-mpm.conf

3.修改conf/extra/httpd-mpm.conf文件 
prefork模式就修改這裏 
<IfModule mpm_prefork_module> 
StartServers 5 # 預先開啓的進程 
MinSpareServers 5 # 最小預留5 
MaxSpareServers 10 # 最大留10 
MaxClients 150 # 最多併發多少個 * 
MaxRequestsPerChild 0 # 最多請求多少次 0不限制 
</IfModule>

winnt模式 
<IfModule mpm_winnt_module> 
ThreadsPerChild 150 # 最大併發數 * 
MaxRequestsPerChild 0 # 最多處理多少次請求 0不限制 
</IfModule>

修改後面有*的那個字段的數值然後重新啓動apache

說明:配置到多大,不一定就可能支撐這麼大的併發,考慮到本身apache所在的機器硬件性能(:內存,CPU,硬盤IO) 
系統是linux/unix,配置perfork 
<IfModule mpm_prefork_module> 
StartServers 5 
MinSpareServers 5 
MaxSpareServers 10 
MaxClients 150 *#併發量 
MaxRequestsPerChild 0 
</IfModule> 
給大家一個合理的建議配置,對大部份網站,中型網站配置 
<IfModule mpm_prefork_module> 
StartServers 5 # 預先啓動 
MinSpareServers 5 
MaxSpareServers 10 # 最大空閒進程 
ServerLimit 1500 *# 用於修改apache編程參數 
MaxClients 1000 *# 最大併發數 
MaxRequestsPerChild 0 
</IfModule> 
:apache2.2以後纔有的ServerLimit這個參數,其中ServerLimit數值大於MaxClients數值

如果網站的pv值 百萬 
ServerLimit 2500 *# 用於修改apache編程參數 
MaxClients 2000 *# 最大併發數 
:調到這就是極限了,要是網站訪問還是大,哪就要增加apache服務器了

 

優化配置10條建議:

1. 控制MaxClients的設置,以避免服務器產生太多的子進程而發生交換。
進程間的數據交換會佔用很大內存,數據交換產生的滯後使用戶總感覺”不夠快”,所以用戶就可能去按”停止”和”刷新”,從而帶來更大的負載。一般建議小網站將MaxClients設置爲12~24。

2. 選擇更好的硬件,CPU、內存、硬盤等等
這句很雞肋啦,如果有更多的銀子,誰不願意換更好的呢?^_^

3. 定期更新操作系統,打上系統補丁;如果你的操作系統支持sendfile()系統調用,則務必安裝帶有此功能的版本或補丁
在支持sendfile的系統中,Apache2可以更快地發送靜態內容而且佔用較少的CPU時間。

4. HostnameLookups設置爲off
儘量較少DNS查詢的次數。如果你使用了任何”Allow from domain”或”Deny from domain”指令(也就是domain使用的是主機名而不是IP地址),則代價是要進行兩次DNS查詢(一次正向和一次反向,以確認沒有作假)。所以,爲了得到最高的性能,應該避免使用這些指令(不用域名而用IP地址也是可以的)。

5. Directory加上FollowSymLinks
如果網站空間中沒有使用 Options FollowSymLinks ,Apache就必須執行額外的系統調用以驗證符號連接。例如:在請求”/index.html”時,Apache將對”/www”、”/www/htdocs”、”/www/htdocs/index.html”執行lstat()調用。而且lstat()的執行結果不被緩存,因此對每一個請求都要執行一次。

6. AllowOverride設置爲None
對於使用虛擬主機的朋友可能會覺得不方便,這樣設置將會使.htaccess中的設置失效,如果實在需要,並且在有條件的情況下,請在conf配置文件中直接寫入rewrite規則

7. 禁用內容協商
儘管在實踐中,內容協商的好處大於性能的損失,如果你很在意那一點點的性能損失,則可以禁止使用內容協商。但是仍然有個方法可以提高服務器的速度,就是不要使用通配符。

8. MaxRequestsPerChild設置爲非0以防止內存泄漏
MaxRequestsPerChild用於控制Apache子進程在何時銷燬,默認爲0,代表永不銷燬子進程,這可能會存在內存泄漏的風險,建議設置爲10000

9. KeepAlive與KeepAliveTimeOut
如果你使用的使mpm_prefork模式(Apache默認安裝),那麼建議你將KeepAlive設置爲off;因爲,開啓keepalive會爲每個客戶端建立一個連接,prefork不會創建線程,估計100個用戶同時訪問你的網站,Apache就會掛了~,如果你實在想開啓,那麼請將KeepAliveTimeOut 時間設置更短些,例如5,默認是60秒呢

10. 不要靜態編譯Apache
儘管會有很多人和你說靜態編譯的好處,同時,你自己也想自己編譯一把,以體驗樂趣~但是,將模塊已靜態方式編譯進Apache絕對不是一個好選擇,尤其是對於缺銀子的站長們來說,一個配置不當,Apache會在啓動時就佔用光你所有的內存,最後拖垮服務器~

 

 

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章