解決Apache長時間占用內存大的問題,Apache 內存優化方法


問:為什么服務器在連續運行多天后或訪問峰值后,進程中的一個Apache.exe占用內存幾百兆不減少?
答:用記事本打開apache2\conf\httpd.conf,
我在centos5上裝了kloxo,找了半天 httpd.conf在 /etc/httpd/conf/目錄下。
查找MaxRequestsPerChild,將MaxRequestsPerChild 0改成MaxRequestsPerChild 50即可。
 影響apache性能的幾個重要參數(conf/httpd.conf中設置)
KeepAlive 是否允許持續連接
MaxKeepAliveRequests 允許的持續連接的最大數
KeepAliveTimeout 持續連接在沒有請求多少秒后切斷
StartServers 最初啟動時啟動多少個服務器進程
MinSpareServers 空閑服務器進程的最小數
MaxSpareServers 空閑服務器進程的最大數
MaxClients 同時處理的請求數(最重要的參數,要少於ServerLimit)
MaxRequestsPerChild 每個子進程處理的最大請求數
它們之前的關系:
prefork控制進程在最初建立“StartServers”個子進程后,為了滿足MinSpareServers設置的需要創建一個進程,等待一秒鍾,繼續創建兩個,再等待一秒鍾,繼續創建四個……如此按指數級增加創建的進程數,最多達到每秒32個,直到滿足MinSpareServers設置的值為止。這種模式可以不必在請求到來時再產生新的進程,從而減小了系統開銷以增加性能。MaxSpareServers設置了最大的空閑進程數,如果空閑進程數大於這個值,Apache會自動kill掉一些多余進程。這個值不要設得過大,但如果設的值比MinSpareServers小,Apache會自動把其調整為MinSpareServers+1。如果站點負載較大,可考慮同時加大MinSpareServers和 MaxSpareServers。MaxRequestsPerChild設置的是每個子進程可處理的請求數。每個子進程在處理了 “MaxRequestsPerChild”個請求后將自動銷毀。0意味着無限,即子進程永不銷毀。雖然缺省設為0可以使每個子進程處理更多的請求,但如果設成非零值也有兩點重要的好處:1、可防止意外的內存泄漏。2、在服務器負載下降的時侯會自動減少子進程數。

  ServerLimit 2000
  StartServers 10
  MinSpareServers 10
  MaxSpareServers 15
  MaxClients 1000
  MaxRequestsPerChild 2048

調試過程中用到的指令:
# ps -ef|grep http|wc -l //查看請求總數
# cat /proc/loadavg //查看平均負載(loadavg),loadavg高於1,表明任務隊列出現了等待,CPU忙不過來了。超過2以上就會明顯感到性能降低了
# netstat -ant | grep :80 | wc -l //查看TCP連接數
# top //查看系統運行情況
====================================================================
apache的內存使用
apache進程在使用內存時,是“漸長”的。也就是說,直到這個進程死掉,使用內存的數量是一直增長而不會減少的。這樣的話,apache進程使用內存的多少,就決定於你的應用程序最大使用內存量了。
keepalive參數
KeepAliveTimeout 這個參數決定了,在什么都不做之前,一個http進程能夠等待多長時間?設想一下,如果keepalive設置為on,而 keepalivetimeout設置為一個比較大的數字,apache占用內存會很快的增長。這是因為,一個apache進程完成了一個任務(並達到了一定的內存占用,想一下“漸進”模式),並不會馬上退出,而是等待一個keepalivetimeout時間。假設用戶的鏈接請求持續不斷的到來,則積累起來的無用的apache進程就會相當多,直到timeout,這些進程才會被殺死。
但是,keepalive的確對於靜態的文件,比如圖像文件的傳送是很有效的,因此,keepalive要設置為on,(off)但是keepalvietimeout要設置的小些,比如5s 15
MaxRequestsPerChild
這個參數是說,apache進程在處理了多少個請求之后,必須退出,重新開始,以免在處理中的內存問題。
對於php腳本來說,把這個參數設置的小一些是有好處的,可以避免程序使用的內存持續增長對apache帶來的壓力:讓這個參數定期釋放內存,因為php是在腳本執行完畢后,自動釋放只用的資源(內存)的。
比如設置為50?如果太小的話,重新產生一個apache進程也是要消耗資源的,這是一個平衡問題。
 
--------------------------------------
案例:
Apache 的 httpd 進程占用大量內存原因及其解決方案
有一台服務器 IBM P550 小型機上的 IHS 在連續運行幾天后,其中的一個 httpd 進程占用內存接近幾百兆。

IHS 其實就是 Apache ,AIX 5.3 下運行在 worker 方式下,它被看作 Apache 未來的主流工作模式,它是一種多進程與多線程混合的模式。
Apache的主流工作模式MPM模式。MPM是Multi-Processing-Modules的簡稱,意思是多道處理模塊。MPM模塊有不同的種類。現在用的比較多的MPM種類主要是prefork和worker。prefork的工作方式是多個進程工作,每個進程會在處理一定數量的請求后結束(這個數量可能是無窮),沒有線程的概念。worker被看作apache未來的主流工作模式,它是一種多進程與多線程混合的模式。

配置文件 httpd.conf 中 work 的參數配置項:

<IfModule worker.c>
ThreadLimit         100
ServerLimit         250
StartServers         8
MaxClients         25600
MinSpareThreads     100
MaxSpareThreads     300
ThreadsPerChild     100
MaxRequestsPerChild  0
</IfModule>

關鍵的問題出現在 MaxRequestsPerChild 參數。MaxRequestsPerChild這個指令設定一個獨立的子進程將能處理的請求數量。
在處理“MaxRequestsPerChild 數字”個請求之后,子進程將會被父進程終止,這時候子進程占用的內存就會釋放,如果再有訪問請求,父進程會重新產生子進程進行處理。
如果MaxRequestsPerChild缺省設為0(無限)可以使每個子進程處理更多的請求,不會因為不斷終止、啟動子進程降低訪問效率。

但如果占用了200~300M內存,即使負載下來時占用的內存也不會減少。內存較大的服務器可以設置為0或較大的數字。內存較小的服務器不妨設置成30、50、100,以防內存溢出。

 

Apache MPM選擇下的ServerLimit和ThreadLimit大小
1、環境
編譯Apache時選則worker工作模式
配置如下:

    StartServers           5   
    MaxClients          2000   
    MinSpareThreads      25   
    MaxSpareThreads      200   
    ThreadsPerChild      100   
    MaxRequestsPerChild   0

當重啟Apache時候出現如下警告:
[root@localhost conf]# /etc/init.d/apachectl restartWARNING: ThreadsPerChild of 100 exceeds ThreadLimit value of 64threads, lowering ThreadsPerChild to 64. To increase, please see the ThreadLimit directive.WARNING: MaxClients (2000) is not an integer multiple of ThreadsPerChild (64), lowering MaxClients to 1984 for a maximum of 31 child processes,WARNING: MaxClients of 1984 would require 31 servers, and would exceed the ServerLimit value of 16. Automatically lowering MaxClients to 1024.  To increase, please see the ServerLimit directive.

需要對ServerLimit和ThreadLimit進行設置
查看手冊

ThreadLimit 指令

說明 每個子進程可配置的線程數上限
語法 ThreadLimit number
默認值 參見下面的說明
作用域 server config
狀態 MPM
模塊 mpm_winntworker
兼容性 僅用於2.0.41及以后版本的mpm_winnt

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

使用這個指令時要特別當心。如果將ThreadLimit設置成一個高出ThreadsPerChild實際需要很多的值,將會有過多的共享內存被分配。如果將ThreadLimitThreadsPerChild設置成超過系統的處理能力,Apache可能無法啟動,或者系統將變得不穩定。該指令的值應當和ThreadsPerChild可能達到的最大值保持一致。

對於mpm_winntThreadLimit的默認值是1920;對於其他MPM這個值是64

注意

Apache在編譯時內部有一個硬性的限制"ThreadLimit 20000"(對於mpm_winnt是"ThreadLimit 15000"),你不能超越這個限制。

 

ServerLimit 指令

說明 服務器允許配置的進程數上限
語法 ServerLimit number
默認值 參見下面的說明
作用域 server config
狀態 MPM
模塊 preforkworker

對於preforkMPM,這個指令設置了MaxClients最大允許配置的數值。對於workerMPM,這個指令和ThreadLimit結合使用設置了MaxClients最大允許配置的數值。任何在重啟期間對這個指令的改變都將被忽略,但對MaxClients的修改卻會生效。

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

對於preforkMPM,只有在你需要將MaxClients設置成高於默認值256的時候才需要使用這個指令。要將此指令的值保持和MaxClients一樣。

對於workerMPM,只有在你需要將MaxClientsThreadsPerChild設置成需要超過默認值16個子進程的時候才需要使用這個指令。不要將該指令的值設置的比MaxClients 和ThreadsPerChild需要的子進程數量高。

注意

Apache在編譯時內部有一個硬限制"ServerLimit 20000"(對於preforkMPM為"ServerLimit 200000")。你不能超越這個限制。


 

按照配置MaxClient 為 2000

不要將該指令的值設置的比MaxClients 和ThreadsPerChild需要的子進程數量高。

ServerLimit=MaxClient / ThreadPerChild = 2000 / 100 = 20

所以ServerLimit設置不能比20更高

如果將ThreadLimit設置成一個高出ThreadsPerChild實際需要很多的值,將會有過多的共享內存被分配。

ThreadLimit設置最好不要超過ThreadsPerChil的值,ThreadPerChild = 100
所以 ThreadLimit設置為100


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM