解決PHP-FPM進程導致的服務器內存佔用

最近php-fpm服務器經常內存偏高。

最簡單也是馬上見效的方法是重啓服務,乾脆重啓服務器,這個對於某些臨時進程導致的內存虛高可能有效,這裏顯然是不行滴。很可能影響到業務。

解決
查看服務器內存及進程狀況

 

php-fpm參數概述
下面對每個參數的意義進行簡要的概述分析

pm=dynamic

該項共有三種設置方式 static 、 dynamic 、ondemand

一種是pm = static,始終保持一個固定數量的子進程,這個數由pm.max_children定義,這種方式很不靈活,也通常不是默認的。

另一種是pm = dynamic,他是這樣的,啓動時,會產生固定數量的子進程(由pm.start_servers控制)可以理解成最小子進程數,而最大子進程數則由pm.max_children去控制,這樣的話,子進程數會在最大和最小數範圍中變化,還沒有完,閒置的子進程數還可以由另2個配置控制,分別是pm.min_spare_servers和pm.max_spare_servers,也就是閒置的子進程也可以有最小和最大的數目,而如果閒置的子進程超出了pm.max_spare_servers,則會被殺掉。(注意,pm.max_spare_servers應小於pm.max_children)

第三種就是pm = ondemand模式,這種模式和pm = dynamic相反,把內存放在第一位,他的工作模式很簡單,每個閒置進程,在持續閒置了pm.process_idle_timeout秒後就會被殺掉,有了這個模式,到了服務器低峯期內存自然會降下來,如果服務器長時間沒有請求,就只會有一個php-fpm主進程,當然弊端是,遇到高峯期或者如果pm.process_idle_timeout的值太短的話,無法避免服務器頻繁創建進程的問題,因此pm = dynamic和pm = ondemand誰更適合視實際情況而定。

可以看到,pm = dynamic模式非常靈活,也通常是默認的選項。但是,dynamic模式爲了最大化地優化服務器響應,會造成更多內存使用,因爲這種模式只會殺掉超出最大閒置進程數(pm.max_spare_servers)的閒置進程,比如最大閒置進程數是30,最大進程數是50,然後網站經歷了一次訪問高峯,此時50個進程全部忙碌,0個閒置進程數,接着過了高峯期,可能沒有一個請求,於是會有50個閒置進程,但是此時php-fpm只會殺掉20個子進程,始終剩下30個進程繼續作爲閒置進程來等待請求,這可能就是爲什麼過了高峯期後即便請求數大量減少服務器內存使用卻也沒有大量減少,也可能是爲什麼有些時候重啓下服務器情況就會好很多,因爲重啓後,php-fpm的子進程數會變成最小閒置進程數,而不是之前的最大閒置進程數。

max_requests

即是說每個進程若超過這個數目(跟php進程有一點點關係,關 系不大),就自動殺死.

max_children

最大進程數,一般來說一臺服務器正常情況下每一個php-fpm所耗費的內存在40M左右,理想最大進程數可計算爲1000/40=25,但是實際上內存不止有php-fpm在佔用,故可根據實際情況來,適當減小使得內存不會因php-fpm進程過多而耗盡。而如果我 的”max_children”設置的較小,比如5-10個,那麼php-fpm就會“很累”,處理速度也很慢,等待的時間也較長。如果長時間沒有得到處 理的請求就會出現504 Gateway Time-out這個錯誤。

request_terminate_timeout

據你服務器的性能進行設定。一般來說性能越好你可以設置越高,20分鐘-30分鐘都可以。由於我的服務器PHP腳本需要長時間運行,有的可能會超過10分 鍾因此我設置了1200秒,這樣不會導致php-fpm死掉而出現502 Bad gateway這個錯誤。

pm.start_servers

動態方式下的起始php-fpm進程數量

pm.min_spare_servers

動態方式下的最小php-fpm閒置進程數

pm.min_spare_servers

動態方式下的最大php-fpm閒置進程數量

由於方便管理把php-fpm配置文件拆開了。在/opt/plesk/php/7.1/etc/php-fpm.d目錄下

 

這樣我們就可以定位到是哪個佔用

[root@orion php-fpm.d]# ls

aabus.com.conf coachrun.com.conf jadiamortgage.com.conf jadia.net.conf livechat.taketours.com.conf lltours.com.conf sunshineboston.com.conf

[root@orion php-fpm.d]# vim livechat.taketours.com.conf

這是之前的配置文件:

pm = ondemand #按需ondemand
pm.max_children = 5 #最大進程數
pm.max_spare_servers = 1 #動態方式下的最大php-fpm閒置進程數量
pm.min_spare_servers = 1 #動態方式下的最小php-fpm閒置進程數
pm.process_idle_timeout = 10s #按需方式下多長時間殺掉php-fpm子進程,直到master進程
pm.start_servers = 1 #動態方式下的起始php-fpm進程數量

修改後的配置:

pm = ondemand
pm.max_children = 5
pm.max_spare_servers = 2
pm.min_spare_servers = 2
pm.process_idle_timeout = 10s
pm.start_servers = 1
pm.max_requests = 1024 指的是每個子進程在處理了1024個請求數量之後就重啓

跟蹤一陣時間後發現內存在30000kb左右波動,進程使用的物理內存百分比才0.1%


參考文章:  https://www.centos.bz/2018/03/php-fpm進程過多,內存耗盡/

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