php-fpm進程佔用CPU過高| php-cgi進程過多

一般情況下,PHP-CGI只在用戶訪問的時候會佔用CPU資源,如果服務器上的PHP-CGI進程佔用了非常多的CPU,但是訪問流量卻非常少。這顯然是一個不正常的現象

1.使用 top 找出CPU最高的進程pid

2 ll /proc/PID/fd //通過PID找到哪個文件操作的進程,進而知道問題所在

3 strace -p PID(進程數) 來跟蹤進程

Linux分析進程佔用內存最高和佔用CPU最高

這裏只顯示最高的前5個,如果想顯示更多的話,可以自己修改:

查看佔用內存最高的5個進程

ps aux | sort -k4nr | head -n 5

查看佔用cpu最高的5個進程

ps aux | sort -k3nr | head -n 5

查看是否是硬件問題

  方式:top 命令

  主要查看:load average(平均負載),這是一個4核8G內存的服務器

 

  1分鐘平均負載:2.32;

  5分鐘平均負載:2.18;

  15分鐘平均負載:3.95;

  load average 中3個數的含義,如果是1核cpu,那麼不能超過1,4核那麼就不能超過4,15分鐘可以代表長期,5分鐘代表中期,1分鐘代表短期,所以先看15分鐘

  大神詳解load average

  可以說它現在的平均負載接近了它的cpu總核數:4;需要考慮服務器配置升級!

php-fpm.conf 文件一般位於 /www/server/php/70/etc 目錄下,注意 70 是php的版本號,需要根據你的php版本變更。

 

1 ---- 此文章是單個PHP進程使用CPU過高
公司服務器CPU佔用過高,報警了,第一反應是登錄服務器, top 命令查看當前進程,再輸入 P 按cpu排序 :

 

果然看到有多個php-fmp進程佔用cpu過高,都達到100%了

於是打算監聽一下進程,看看在執行什麼操作,使用 strace 命令:

#監聽進程 strace -o /tmp/output.txt -T -tt -F -e trace=all -p 7757
#查看log tail -f /tmp/output.txt


結果還沒看出來什麼,cpu佔用率已經下來了,那幾個進程已經結束了。最後通過 php慢日誌 發現了端倪。

php慢日誌開啓條件,需要在 php-fpm.conf 配置如下:

request_slowlog_timeout = 1 #腳本超時秒數,超過1稍都算慢了
slowlog = /var/log/php.log.slow #記錄慢日誌路徑

查看近1000條php慢日誌:

tail -n 1000 /var/log/php.log.slow
經查找發現了罪魁禍首,是前同事留下的一個大遞歸操作有問題:

然後優化代碼就可以了。

這種個別php-fpm進程cpu佔用過高,基本上是由於程序本身存在問題(如程序無限循環邏輯),優化程序後如果還得不到解決,那就如網上所說需要考慮 php-fpm.conf 裏面的一些配置參數了,以及升級服務器。

此文:https://blog.csdn.net/msllws/article/details/107090542

 

2---此文章是單個PHP進程使用CPU過高
當我打開寶塔面板的時候,驚呆了,
服務器 cup使用率100%,負載狀態100%,瞬間從一萬米高空墜下,周身氣溫降到零下。

看到這種情況,我只能努力的平復面臨崩潰的心態,右手撫額,由上而下,滑過鼻尖的時候深吸一口氣,
假裝淡定的 一頓shell操作,查看源頭(其實只會一個top \:手動狗頭),隨之百度一番,過程萬分艱辛,請謹慎食用。

step1:top大法
[root@xxxxxxxxxxxxxxxx ~]# top


記下進程號
step2:找到罪魁禍首
[root@xxxxxxxxxxxxxxxx ~]# ll /proc/3295/fd


顯示socket最高

至此,分析原因,socket最高,那就應該是跟服務器上的webserver有關,因爲客服項目中用到了workerman,當時部署的時候我還啓動過,問題應該在這裏,
接着查看php進程在做啥,爲啥會佔用如此之高的cpu

step3:分析犯罪心理
[root@xxxxxxxxxxxxxxxx ~]# strace -p 3295


顯示 pcntl_wait() 函數已被禁用,原因找到了(內心狂喜,oh~~~)

step4:物理治療(開開心心的去刪除禁用列表的該函數)


重啓php,讓後觀察cpu狀態,然鵝~~~~ GG,等了幾分鐘之後,依舊沒有絲毫下降的趨勢。
我心裏又慌得一批,難道是我找錯方向了?難道是我技術太菜了?難道是我不配做寫代碼?
靈魂三連問之後,想到php的配置雖然修改了,但是服務器上運行的web服務裏面加載的還是未改動之前的配置,
果斷重啓所有web服務,開啓重啓大法(如果這樣還不行,那就剩下最後的大招了,重啓服務器,哈哈哈哈~~~)
tep5:查看戰果

重啓workerman,運行幾分鐘任然正常,perfect!
原文鏈接:https://blog.csdn.net/qq_39376990/article/details/109573083

3. PHP-fpm(php-cgi)的進程數過多
首先使用 free -m 指令查看當前服務器執行狀況:

  

  可以看到當前我這設備的內存消耗不多,也能看到我是2G內存

如果我們發現php-cgi進程數量過多時,雖然單個php-cgi佔用內存並不算太大,但是大量的php-cgi進程就有點恐怖了。幾乎佔盡了全部內存(可自動累加其使用的內存率),因此 我們可通過設置php-cgi數量來緩解內存消耗過高的問題,

php-cgi由php-fpm管理,因此可以斷定,是由於php-fpm配置文件中的max_children參數配置不當,才導致打開過多的php-cgi進程。所以要適當調整下max_children的設置。

  然後再用 top 命令 m 參數 查看內存情況

  再使用:ps auxw|head -1;ps auxw|sort -rn -k4|head -40 查看消耗內存最多的前40個進程

  查看通過命令查看服務器上一共開了多少的 php-cgi 進程:ps -fe |grep "php-fpm"|grep "pool"|wc -l

  查看已經有多少個php-cgi進程用來處理tcp請求:netstat -anp|grep "php-fpm"|grep "tcp"|grep "pool"|wc -l

  設置PHP-FPM的進程數:vi /www/server/php/70/etc/php-fpm.conf(根據實際情況變化)找到 pm.max_children 字段,設置一個合理的值,比之前的小

  pm.max_spare_servers : 該值表示保證空閒進程數最大值,如果空閒進程大於此值,此進行清理 pm.min_spare_servers : 保證空閒進程數最小值,如果空閒進程小於此值,則創建新的子進程;

  這兩個值均不能不能大於 pm.max_children 值,通常設置 pm.max_spare_servers 值爲 pm.max_children 值的60%-80%。

  正常情況下,一個php--fpm佔用內存20~30M

Nginx使用的php-fpm的三種進程管理方式及優化 pm.start_servers pm.max_children參數說明

4. PHP-fpm(php-cgi)的進程數過多
發現問題以後,首先使用 free -m 指令查看當前服務器執行狀況:

 

可以看到我的服務器內存是2G的,但是目前可用內存只剩下70M,內存使用率高達92%,很有可能是內存使用率過高導致數據庫服務掛斷。

繼續看詳細情況,使用 top 指令:

 

然後再看指令輸出結果中詳細列出的進程情況,重點關注第10列內存使用佔比:

 

發現CPU使用率不算高,也排除了CPU的問題,另外可以看到數據庫服務佔用15.2%的內存,內存使用過高時將會擠掉數據庫進程(佔用內存最高的進程),導致服務掛斷,所以我們需要查看詳細內存使用情況,是哪些進程耗費了這麼多的內存呢?

使用指令:

1

ps auxw|head -1;ps auxw|sort -rn -k4|head -40

查看消耗內存最多的前40個進程:

 

查看第四列內存使用佔比,發現除了mysql數據庫服務之外,php-fpm服務池開啓了太多子進程,佔用超過大半內存,問題找到了,我們開始解決問題:設置控制php-fpm進程池進程數量。

解決問題

通過各種搜索手段,發現可以通過配置 pm.max_children 屬性,控制php-fpm子進程數量,首先,打開php-fpm配置文件,執行指令:

1

vi /etc/php-fpm.d/www.conf

找到 pm.max_children 字段,發現其值過大:

 

如圖, pm.max_children 值爲50,每一個進程佔用1%-2.5%的內存,加起來就耗費大半內存了,所以我們需要將其值調小,博主這裏將其設置爲25,同時,檢查以下兩個屬性:

pm.max_spare_servers : 該值表示保證空閒進程數最大值,如果空閒進程大於此值,此進行清理 pm.min_spare_servers : 保證空閒進程數最小值,如果空閒進程小於此值,則創建新的子進程;

這兩個值均不能不能大於 pm.max_children 值,通常設置 pm.max_spare_servers 值爲 pm.max_children 值的60%-80%。

最後,重啓php-fpm

1

systemctl restart php-fpm

再次查看內存使用情況, 使用內存降低很多:

 

之後經過多次觀察內存使用情況,發現此次改進後,服務器內存資源消耗得到很大緩解。

ps:查看php-fpm開啓的進程數以及每個進程的內存限制

1.通過命令查看服務器上一共開了多少的 php-cgi 進程

1

ps -fe |grep "php-fpm"|grep "pool"|wc -l

2.查看已經有多少個php-cgi進程用來處理tcp請求

1

netstat -anp|grep "php-fpm"|grep "tcp"|grep "pool"|wc -l

3.linux+nginx+php環境中,每個php-fpm進程的內存限制

設置方法:

編輯php-fpm.conf配置文件內的屬性php_admin_value[memory_limit] = 128M( 後邊的數字可以隨便更改:32M,64M,128M,256M,512M,這個設置可根據你的服務器內存大小和你的需求來寫,修改後要加載一下php-fpm服務。

5. PHP-fpm(php-cgi)的進程數過多
機房一臺服務器運行一段時間後,突然發現系統資源即將被耗盡!

1)top命令查看一下系統的cpu ram swap的使用情況

 

 

由上圖分析,可以看出 1--共有602個進程,但其中有601個進程休眠了。 這就有點不對勁,這臺服務器的內核進程也就80個左右,加上memcached, nginx, mysqld,也不會超出90個,除了這些,剩下的只有php-fpm管理的php-cgi了。 2--CPU顯示,CPU壓力並不大,可以說沒有壓力。 3--內存使用概要,發現4G的內存,消耗得所剩餘無幾(free+buffers),95%以上的內存都已分配;交互空間使用情況,暫時不去關心。指令top還列出了佔用資源最多的進程,運行時間最久(Time+)的mysqld(約2小時)佔用資源並不是最多。 4--再看php-cgi,單個php-cgi佔用的內存也不算多。 所以,可以大膽地猜想:服務器內存資源比較緊張,並沒有被某個進程佔用大量內存,有可能被某些掛起的進程佔着內存沒有釋放。通過free進一步監控內存使用情況,驗證我們的想法。

2)查看ram的使用情況

 

 

先來看Mem統計信息,total表示物理內存總量,約4G。used,表示已分配內存,分配了並不表示使用了,包括(buffer&cached)。free指未分配的內存,buffers與cached表示分配了但還沒有被使用的內存。第二行(buffers/cache)的,used表示真正被使用了內存,由第一行的(used-buffer-cached)得到,free則表示還沒有被使用的內存,由第一行的(free+buffer+cached)得到。Swap行則表示內存交換使用情況,少量的(不頻繁地)swpd,是不會影響服務器性能的,因爲系統需要將V類型的內存頁面交換出去或者調整了buffer與cached的大小。但是頻繁地swpd,則有可能意味着服務器物理內存不足,小於指定的swap額定值,需要換出內存頁。

查看free結果的時候,主要查看第二行。一眼就能看出4G的內存,其中有3898M內存被用了,還有49M內存沒有,都快用完了。 這也證實了第一步的猜想,內存被用完! 這裏,可以進一步猜想,內存空間嚴重不足的情況下,進程會被blocked,系統會不斷地將不用的數據換出so,將要用的數據讀入si。 下面通過vmstat進一步驗證這個猜想。

3)vmstat監控內存的使用情況(執行命令:vmstat)

 

 

作爲對內存監控,比較重要的還是swpd、free、si、so。 一般系統不繁忙的狀態下,可以看到swpd,so的值不會持續很高,經常爲0。 這裏看到swpd值爲1.5G,以及free值很小,再一次表明物理內存不足。其中si報告了每秒從swap區移入到物理內存的內存總量,so報告了每秒從物理內存移出到swap區的內存總量。 當然,si有時較大,並不要過份的焦慮,經常碰到一個程序需要較大內存來讀寫媒體文件時,si值就會變大。反倒是so,它通常是一個內存緊缺的一個信號,如果長時間這個值一直保持較大的話,則很有可能內存不夠,小額波動,可以不用理會。接下來,可以通過ps找出消耗內存的元兇。

4)ps找出消耗內存的元兇(執行命令:ps -A -sort -rss -o comm,pmem,pcpu|uniq -c|head -15)

 

 

指令ps比較常用,也比較簡單。從上面報告結果中可以一眼看到php-cgi這個進程。雖然單個php-cgi佔用內存並不算太大,但是503個php-cgi進程,就有點恐怖了。幾乎佔盡了全部內存(503*0.3%)。php-cgi由php-fpm管理,因此可以斷定,是由於php-fpm配置文件php.ini中的max_children參數配置不當,才導致打開過多的php-cgi進程。所以要適當調整下max_children的設置。

原文鏈接:https://blog.csdn.net/nei504293736/article/details/117255756

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