右鍵已鎖定
logo

Apache 記憶體吃光調教

最近常發現Apache把我的VPS記憶體吃光後,被kernel幹掉在重啟的狀況
以下系統是centos 32bit 512MB


Out of memory: Kill process 9502 (httpd) score 33 or sacrifice child
Killed process 9502 (httpd) total-vm:70580kB, anon-rss:32324kB, file-rss:0kB

仔細觀察幾天,發現我即使設定cron job讓apache每天重新啟動也沒辦法改善這個狀況
因為apache啟動沒多久,記憶體就會吃滿….這到底是WTF

於是只好開始調整apache的config
網路上人家說先從降request著手
於是我就這樣設定


KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 2


StartServers 1
MinSpareServers 3
MaxSpareServers 5
ServerLimit 15
MaxClients 15
MaxRequestsPerChild 2000

雖然有點好笑…但目前看來還蠻有用的
至少記憶體沒再飆升


09:10:01 AM 166080 345072 67.51 31844 68500 428328 41.37
09:20:01 AM 10204 500948 98.00 32108 69048 608012 58.72
09:20:01 AM kbmemfree kbmemused %memused kbbuffers kbcached kbcommit %commit
09:30:01 AM 6956 504196 98.64 32336 67780 615180 59.41
09:40:01 AM 6816 504336 98.67 32748 68420 622752 60.14
09:50:01 AM 293176 217976 42.64 33116 69008 237652 22.95
10:00:01 AM 162084 349068 68.29 33364 69028 375572 36.27
10:10:01 AM 157284 353868 69.23 33728 70280 379044 36.61
10:20:01 AM 166308 344844 67.46 33980 70268 352140 34.01
10:30:01 AM 166060 345092 67.51 34240 70268 351668 33.96

9:10我重開,過10分鐘,記憶體又飆到98%
9:40上config,記憶體降到42%,後來升到68%就穩定了
這是我拿digital ocean的VPS測試
這台VPS只有512MB,所以要節省的用
再加上網站本來就沒甚麼人,憑甚麼吃這麼多記憶體= =

來講一下設定檔的詳細功能
KeepAlive 設定apache在處理完client的http request之後是否中斷TCP連線,或是持續一段時間在斷掉
因為我的網站有引用蠻多JavaScript、JQuery、圖片、CSS等等靜態的東西,所以設定打開是比較適合的
如果你的網站都是程式即使生成的動態網頁,比如JAVA等等,那關閉比較好

KeepAliveTimeout 就是設定持續多長的時間關閉連線,為什麼設定2秒呢
假設我設定10秒,每個使用者連到你的網站都會keep 10秒鐘
假設apache每秒處理50個連線,每個連線佔4M,這樣就有10x50x4=2G
這樣就耗掉你的2G記憶體了,而且連線被占住意味著apache會無法接受新連線
所以可以發現打開KeppAlive設定相當耗記憶體
但我只有512MB,不是高富帥server有96G可以用,所以只好調低秒數

MaxKeepAliveRequests 這個是設定最多可以keep幾個連線
這沒有一定的值,不過以我的狀況還是不要設太高
可以依照需求調整,調高一點就是耗記憶體

Apache有兩種MPM功能,一個是prefork,一個是worker
所以你會發現config裡有兩個設定
MPM是甚麼自己GOOGLE吧,不然這篇要寫成一本書了
反正就想像他是多核心的處理器就好了



StartServers 1
MinSpareServers 3
MaxSpareServers 10
ServerLimit 15
MaxClients 15
MaxRequestsPerChild 2000


StartServers 4
MaxClients 300
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestsPerChild 0

怎麼知道自己的apache是跑在哪個MPM模式呢?


[root@server ~]# httpd -l
Compiled in modules:
core.c
prefork.c
http_core.c
mod_so.c
[root@server ~]#

這樣我就知道我的apache是跑prefork模式
所以我只要設定prefork就好
相反的你設定worker是沒用的

稍微講一下概念
client發出request,request可能有很多connection
apache接到request 就會fork一個child去處理request
當child被request的connection撐爆了,apache就會把它砍掉
然後再生一個新的來處理

MaxClients 是最多可同時連線的connection數,記憶體不多就設少一點吧

ServerLimit 要大於等於MaxClients數量

StartServers 是指apache啟動時最小的process數量,也就是可同時處理的request數
每個process都需要記憶體的,而且apache會自動調整process數量,所以記憶體有剩的話apache會自動增加(fork)process
所以一開始不用設太多,這邊process通常中文叫做子進程,就是apache生的小孩就對了

MaxRequestsPerChild 一個process可以處理的最大request數量,這個千萬不要調低
調低會因為request超過設定數量,造成CPU飆高
當數量達到你設定的值,apache就會把它的小孩殺掉
然後再生一個小孩出來處理,一直重複產生、殺掉,這時CPU還不飆高嗎?網站不變慢?
因為每個小孩都要吃一定量的記憶體,小孩多記憶體吃更多
那不如我們一開始就設定好一個小孩可以吃多一點的request
至少設定1000以上比較安全
但如果記憶體多(比如96GB),可以一開始就在Startserver那邊設定很多小孩
很多小孩來幫忙處理連線,效能當然好XD

7,230 次瀏覽