您好,登錄后才能下訂單哦!
一、php-fpm.conf 主要配置參數
pm = dynamic; 表示使用哪種進程數量管理方式
dynamic 表示 php-fpm 進程數是動態的,最開始是 pm.start_servers 指定的數量,如果請求較多,則會自動增加,保證空閑的進程數不小于pm.min_spare_servers,如 果進程數較多,也會進行相應清理,保證多余的進程數不多于 pm.max_spare_servers;
static 表示 php-fpm 進程數是靜態的,進程數自始至終都是 pm.max_children 指定的數量,不再增加或減少。
pm.max_spare_servers = 35; 動態方式下的最大php-fpm進程數量
注意:數值設置,參考自己的實際硬件配置,可以參考 總內存/30M 來計算。
如果 pm 設置為 static,那么其實只有 pm.max_children 這個參數生效。系統會開啟設置數量的 php-fpm 進程。
如果 pm設置為 dynamic,那么 pm.max_children 參數失效,后面3個參數生效。系統會在 php-fpm 運行開始的時候啟動 pm.start_servers 個 php-fpm 進程,然后根據系統的需求動態在 pm.min_spare_servers 和 pm.max_spare_servers 之間調整 php-fpm 進程數。
1、pm 方式選擇
事實上,跟 Apache 一樣,運行的 PHP 程序在執行完成后,或多或少會有內存泄露的問題。這也是為什么開始的時候一個 php-fpm 進程只占用 3M 左右內存,運行一段時間后就會上升到 20-30M 的原因了。
對于內存大的服務器(比如8G以上)來說,用靜態的 max_children 實際上更為妥當,因為這樣不需要進行額外的進程數目控制,會提高效率。因為頻繁開關 php-fpm 進程也會有時滯,所以內存夠大的情況下開靜態效果會更好。數量也可以根據 總內存/30M 得到,比如 8GB 內存可以設置為100,那么 php-fpm 耗費的內存就能控制在 2G-3G 的樣子。
如果內存稍微小點,比如 1~2G,那么指定動態的進程數量更加有利于服務器的穩定。這樣可以保證 php-fpm 只獲取夠用的內存,將不多的內存分配給其他應用去使用,會使系統的運行更加暢通。
對于小內存的服務器來說,比如 256M 內存的 VPS,即使按照一個 20M 的內存量來算,10個 php-cgi 進程就將耗掉200M內存,那系統的崩潰就應該很正常了。
因此應該盡量地控制 php-fpm 進程的數量,大體明確其他應用占用的內存后,給它指定一個靜態的小數量,會讓系統更加平穩一些。
或者使用動態方式,因為動態方式會結束掉多余的進程,可以回收釋放一些內存,所以推薦在內存較少的服務器或VPS上使用,具體最大數量根據 總內存/20M 得到。
比如說 512M 的 VPS,建議 pm.max_spare_servers 設置為 20。至于 pm.min_spare_servers,則建議根據服務器的負載情況來設置,比較合適的值在 5~10 之間。
總結:內存小的建議用動態(pm = dynamic),內存大的建議用靜態(pm = static)。
2、pm.max_children 設置多大
這個值原則上是越大越好,php-cgi的進程多了就會處理的很快,排隊的請求就會很少。
設置”max_children” 也需要根據服務器的性能進行設定。
計算方式如下:
一般來說一臺服務器正常情況下每一個php-cgi所耗費的內存在20M~30M左右,因此我的”max_children”我設置成40個,20M*40=800M也就是說在峰值的時候所有PHP-CGI所耗內存在800M以內,低于我的有效內存2Gb。
而如果我 的”max_children”設置的較小,比如5-10個,那么php-cgi就會“很累“,處理速度也很慢,等待的時間也較長,占用的CPU也很高。
如果長時間沒有得到處理的請求就會出現 504 Gateway Time-out 這個錯誤,而正在處理的很累的那幾個php-cgi如果遇到了問題就會出現 502 Bad gateway 這個錯誤。
max_children較好的設置方式根據req/s(吞吐率,單位時間里服務器處理的最大請求數,單位req/s)來設置,若程序是 100 req/s 的處理能力,那么就設置 100比較好,這是動態來調整的。
3、request_terminate_timeout 設置多大
計算方式如下:
如果你的服務器性能足夠好,且寬帶資源足夠充足,PHP腳本沒有循環或BUG的話你可以直接將”request_terminate_timeout”設 置成0s。0s的含義是讓PHP-CGI一直執行下去而沒有時間限制。
而如果你做不到這一點,也就是說你的PHP-CGI可能出現某個BUG,或者你的寬帶不夠充足或者其他的原因導致你的PHP-CGI能夠假死那么就建議你給”request_terminate_timeout”賦一個值,這個值可以根 據你服務器的性能進行設定。
一般來說性能越好你可以設置越高,20分鐘-30分鐘都可以。由于我的服務器PHP腳本需要長時間運行,有的可能會超過10分鐘因此我設置了900秒,這樣不會導致PHP-CGI死掉而出現502 Bad gateway這個錯誤。
二、配置 php 慢日志,用于監控
1、開啟slow log方法
如果你使用php-fpm來管理php的話,你可以通過如下方法開啟:
首先打開 php-fpm.conf 配置文件。
vim /usr/local/php/etc/php-fpm.conf
PHP 5.3.3 之前設置如下:
<value name="request_slowlog_timeout">5s</value>
< value name="slowlog">logs/php-fpm-slowlog.log</value>
或
PHP 5.3.3 之后設置以下如下:
request_slowlog_timeout = 5s
slowlog = /usr/local/php/var/log/php-fpm-slowlog.log
request_terminate_timeout = 10s
說明:
2、slow log使用
開啟后,如果有腳本執行超過指定的時間,就會在指定的日志文件中寫入類似如下的信息:
[06-Dec-2017 20:05:31] [pool www] pid 22271
script_filename = /home/wwwroot/default/tz/tz.php
[0x00007f75e662a398] preg_match_all() /home/wwwroot/default/tz/tz.php:453
[0x00007f75e6627f08] sys_linux() /home/wwwroot/default/tz/tz.php:410
由于我把slow log日志放在 /usr/local/php/var/log/php-fpm-slowlog.log 這里,只需要查看此日志即可!
vim /usr/local/php/var/log/php-fpm-slowlog.log
4、slow log 分析
下面是一張日志圖片,來做一個簡單的分析
說明:
開啟后,在錯誤日志文件(php-fpm.log)中也有相關記錄。如下:
[06-Dec-2017 20:59:53] NOTICE: finished trace of 31450
[06-Dec-2017 20:59:56] WARNING: [pool www] child 31437, script '/home/wwwroot/default/tz/tz.php' (request: "GET /tz/tz.php") executing too slow (1.047562 sec), logging
[06-Dec-2017 20:59:56] NOTICE: child 31437 stopped for tracing
[06-Dec-2017 20:59:56] NOTICE: about to trace 31437
[06-Dec-2017 20:59:56] NOTICE: finished trace of 31437
[06-Dec-2017 21:00:05] WARNING: [pool www] child 31448, script '/home/wwwroot/default/tz/tz.php' (request: "GET /tz/tz.php") executing too slow (1.013736 sec), logging
[06-Dec-2017 21:00:05] NOTICE: child 31448 stopped for tracing
[06-Dec-2017 21:00:05] NOTICE: about to trace 31448
[06-Dec-2017 21:00:05] NOTICE: finished trace of 31448
[06-Dec-2017 21:00:10] WARNING: [pool www] child 31481, script '/home/wwwroot/default/TTTTT_GAME/index.php' (request: "GET /TTTTT_GAME/index.php") executing too slow (1.134845 sec), logging
[06-Dec-2017 21:00:10] WARNING: [pool www] child 31478, script '/home/wwwroot/default/TTTTT_GAME/index.php' (request: "GET /TTTTT_GAME/index.php") executing too slow (1.169301 sec), logging
[06-Dec-2017 21:00:10] WARNING: [pool www] child 31475, script '/home/wwwroot/default/TTTTT_GAME/index.php' (request: "GET /TTTTT_GAME/index.php") executing too slow (1.009847 sec), logging
[06-Dec-2017 21:00:10] WARNING: [pool www] child 31468, script '/home/wwwroot/default/TTTTT_GAME/index.php' (request: "GET /TTTTT_GAME/index.php") executing too slow (1.019848 sec), logging
[06-Dec-2017 21:00:10] WARNING: [pool www] child 31455, script '/home/wwwroot/default/TTTTT_GAME/index.php' (request: "GET /TTTTT_GAME/index.php") executing too slow (1.147848 sec), logging
[06-Dec-2017 21:00:10] WARNING: [pool www] child 31451, script '/home/wwwroot/default/TTTTT_GAME/index.php' (request: "GET /TTTTT_GAME/index.php") executing too slow (1.076841 sec), logging
[06-Dec-2017 21:00:10] WARNING: [pool www] child 31447, script '/home/wwwroot/default/TTTTT_GAME/index.php' (request: "GET /TTTTT_GAME/index.php") executing too slow (1.119846 sec), logging
[06-Dec-2017 21:00:10] WARNING: [pool www] child 31443, script '/home/wwwroot/default/TTTTT_GAME/index.php' (request: "GET /TTTTT_GAME/index.php") executing too slow (1.177849 sec), logging
[06-Dec-2017 21:00:10] WARNING: [pool www] child 31436, script '/home/wwwroot/default/TTTTT_GAME/index.php' (request: "GET /TTTTT_GAME/index.php") executing too slow (1.092818 sec), logging
[06-Dec-2017 21:00:10] WARNING: [pool www] child 31433, script '/home/wwwroot/default/TTTTT_GAME/index.php' (request: "GET /TTTTT_GAME/index.php") executing too slow (1.162842 sec), logging
[06-Dec-2017 21:00:10] NOTICE: child 31433 stopped for tracing
[06-Dec-2017 21:00:10] NOTICE: about to trace 31433
[06-Dec-2017 21:00:10] ERROR: failed to ptrace(PEEKDATA) pid 31433: Input/output error (5)
[06-Dec-2017 21:00:10] NOTICE: finished trace of 31433
[06-Dec-2017 21:00:10] NOTICE: child 31436 stopped for tracing
[06-Dec-2017 21:00:10] NOTICE: about to trace 31436
三、配置 php-fpm 進程可打開的最大文件句柄數
rlimit_files = 1024
默認1024,此值可以不需要配置
四、php-fpm占用cpu和內存過高100% 解決辦法
服務器php-fpm突然占用cpu和內存過高,它的服務器配置是4核8G內存。由于php-fpm占用cpu過高從而導致經常出現“502 Bad gateway”。
服務器環境:LNMP一鍵安裝包,
用了“雅黑探針”來查看服務器的性能情況,結果如下:
當然,除了用探針之外,如果你在服務器下用系統命令:top也是可以查看的:
1、CPU 指標解釋
Cpu(s): 0.0%us, 0.5%sy, 0.0%ni, 99.5%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
解決辦法如下:
多查看日志,根據日志來做解決,最后就是再查看配置文件,是否需要配置調優?
由于有一些步驟不太好表達出來,大家請簡單的看一下邏輯吧,需要你懂很多方面的東西才能夠明白它。此文中有鏈接的地方請大家一定要看一下,否則你是不能夠明白的。
2、查看它的php-fpm.conf配置
從上面配置文件可以看出,它采用的是動態,默認的啟動進程數是4個,最大的是6個,最小的是4個。
3、查看linux平均負載
從上面可以看出,6 個 php-fpm 進程占用的 cpu 空間都很高,平均負載(load average)情況如下:
1分鐘平均負載:2.32;
5分鐘平均負載:2.18;
15分鐘平均負載:3.95;
可以說它現在的平均負載接近了它的cpu總核數:4;需要考慮服務器配置升級!
4、Linux 平均負載 Load Average
1、 Load Average
系統負載(System Load)是系統CPU繁忙程度的度量,即有多少進程在等待被CPU調度(進程等待隊列的長度)。
平均負載(Load Average)是一段時間內系統的平均負載,這個一段時間一般取1分鐘、5分鐘、15分鐘。
2、查看Load Average
top命令,w命令,uptime等命令都可以查看系統負載;
3、Load Average 的3個數值說明
我拿上圖中的 load average:1.97,2.14,2.99 來舉例:
4、Load Average 值的含義
1、單核處理器
(例如:1個1核cpu)
假設我們的系統是單CPU單內核的,把它比喻成是一條單向馬路,把CPU任務比作汽車。
當車不多的時候,load <1;
當車占滿整個馬路的時候 load=1;
當馬路都站滿了,而且馬路外還堆滿了汽車的時候,load>1;
2、多核處理器
(例如:2個cpu或一個2核的cpu)
我們經常會發現服務器Load > 1但是運行仍然不錯,那是因為服務器是多核處理器(Multi-core)。
假設我們服務器一個CPU是2核,那么將意味我們擁有2條馬路,我們的Load = 2時,所有馬路都跑滿車輛。
提示:
芯片廠商往往在一個CPU內部,包含多個CPU核心,這被稱為多核CPU。
在系統負荷方面,多核CPU與多個CPU效果類似,所以考慮系統負荷的時候,必須考慮這臺電腦有幾個CPU、每個CPU有幾個核心。然后,把系統負荷除以總的核心數,只要每個核心的負荷不超過1.0,就表明電腦正常運行。
3、查看服務器 cpu 信息
cat /proc/cpuinfo
4、查看服務器 cpu 總核心數
grep 'model name' /proc/cpuinfo | wc -l
或
grep -c 'model name' /proc/cpuinfo
5、Load Average 警惕值(單核)
Load < 0.7時:系統很閑,馬路上沒什么車,要考慮多部署一些服務
0.7 < Load < 1時:系統狀態不錯,馬路可以輕松應對
Load == 1時:系統馬上要處理不多來了,趕緊找一下原因
Load > 1時:馬路已經非常繁忙了,進入馬路的每輛汽車都要無法很快的運行
6、Load Average 關鍵值(單核)
通常我們先看15分鐘load,如果load很高,再看1分鐘和5分鐘負載,查看是否有下降趨勢。
1分鐘負載值 > 1,那么我們不用擔心,但是如果15分鐘負載都超過1,我們要趕緊看看發生了什么事情。所以我們要根據實際情況查看這三個值。
現在相信大家都知道,"load average"一共返回三個平均值:1分鐘系統負荷、5分鐘系統負荷,15分鐘系統負荷;
如果只有1分鐘的系統負荷大于1.0,其他兩個時間段都小于1.0,這表明只是暫時現象,問題不大。
如果15分鐘內,平均系統負荷大于1.0(調整CPU核心數之后),表明問題持續存在,不是暫時現象。所以,你應該主要觀察"15分鐘系統負荷",將它作為電腦正常運行的指標。
7、結合具體情況具體分析(單核)
184 total :184個總進程數
4 running:4個正在運行的進程數
143 sleeping:180個睡眠的進程數
0 stoppe:0個停止的進程數
0 zombie:0個凍結進程數
5、更改 php-fpm.conf 配置文件 來做調優
由于服務器是8G內存,按理說應該可以啟動 200 個左右的 php-fpm 進程,于是我修改如下:
除了以上配置測試了之外,我還把“pm = dynamic”修改成了“pm= static”配置來做測試,結果都不理想,具體結果向下看:
6、再一次查看linux平均負載
從上面配置可以看出來,每一個php-fpm雖然占用的cpu空間少了,但是總量依然還是接近100%。
而且平均負載(load average)情況如下:
1分鐘平均負載:289.73;
5分鐘平均負載:264.27;
15分鐘平均負載:179.20;
可以說它現在的平均負載接遠遠超過了總cpu核數:4;必須升級服務器配置。
之所以這么高,除了它本身服務器配置跟不上之外,還有一個就是我把pm.max_spare_servers設置成了512,如果一個線程占用20M內存,則需要512*20;而它現在的服務器只有8G內存4核CPU;因此這個負載才能達到了200多。這里也算是測試的一個小失誤吧!
正常情況下,一個線程占用內存20~30M,8G內存設置100~200就足夠了。
184 total :678個總進程數
4 running:211個正在運行的進程數
143 sleeping:327個睡眠的進程數
0 stoppe:140個停止的進程數
0 zombie:0個凍結進程數
總結:
因為失誤測試,我再重新把配置文件修改成:“pm= static”和 "pm.max_children =100",依然cpu和內存還是占用很高,負載非常的高,這完全是沒有道理的。
試想一下:一個 4 核 8G 內存的服務器,居然線程設置越大,CPU占用越高(設置在內存最大允許范圍),設置越小 CPu 占用越小,這是不正常的。最主要的是,php-fpm線程雖然小,占用cpu空間少了,但是出現502的次數就多了。從而更加說明了目前的服務器目前的配置支撐不了現有的業務。
現在我朋友向總部申請了8核16G內存的服務器,申請成功后,默認開始啟動設置的線程是100,最大線程是200;現在已經恢復正常,如下圖:
從這里也可以說明,有時候出問題并不是你自己的原因,就是服務器硬件配置跟不上的原因。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。