php-fpm的進程數可以根據設置分為動態和靜態。
- 靜態:直接開啟指定數量的php-fpm進程,不再增加或者減少;
- 動態:開始的時候開啟一定數量的php-fpm進程,當請求量變大的時候,動態的增加php-fpm進程數到上限,當空閑的時候自動釋放空閑的進程數到一個下限。
這兩種不同的執行方式,可以根據服務器的實際需求來進行調整。
這里先說一下涉及到這個的幾個參數吧,他們分別是pm、pm.max_children、pm.start_servers、pm.min_spare_servers和pm.max_spare_servers。
pm表示使用那種方式,有兩個值可以選擇,就是static(靜態)或者dynamic(動態)。在更老一些的版本中,dynamic被稱作apache-like。這個要注意看配置文件給出的說明了。
下面4個參數的意思分別為:
- pm.max_children:靜態方式下開啟的php-fpm進程數量。
- pm.start_servers:動態方式下的起始php-fpm進程數量。
- pm.min_spare_servers:動態方式下的最小php-fpm進程數量。
- pm.max_spare_servers:動態方式下的最大php-fpm進程數量。
如果dm設置為static,那么其實只有pm.max_children這個參數生效。系統會開啟設置的數量個php-fpm進程。
如果dm設置為dynamic,那么pm.max_children參數失效,后面3個參數生效。系統會在php-fpm運行開始的時候啟動 pm.start_servers個php-fpm進程,然后根據系統的需求動態在pm.min_spare_servers和 pm.max_spare_servers之間調整php-fpm進程數。
那么,對於我們的服務器,選擇哪種執行方式比較好呢?事實上,跟Apache一樣,我們運行的PHP程序在執行完成后,或多或少會有內存泄露的問題。這也是為什么開始的時候一個php-fpm進程只占用3M左右內存,運行一段時間后就會上升到20-30M的原因了。所以,動態方式因為會結束掉多余 的進程,可以回收釋放一些內存,所以推薦在內存較少的服務器或者VPS上使用。具體最大數量根據 內存/20M 得到。比如說512M的VPS,建議pm.max_spare_servers設置為20。至於pm.min_spare_servers,則建議根據服務器的負載情況來設置,比較合適的值在5~10之間。
然后對於比較大內存的服務器來說,設置為靜態的話會提高效率。因為頻繁開關php-fpm進程也會有時滯,所以內存夠大的情況下開靜態效果會更好。數量也可以根據 內存/30M 得到。比如說2GB內存的服務器,可以設置為50;4GB內存可以設置為100等。
一種是pm = static
,始終保持一個固定數量的子進程,這個數由pm.max_children
定義,這種方式很不靈活,也通常不是默認的。
另一種是pm = dynamic
,他是這樣的,啟動時,會產生固定數量的子進程(由pm.start_servers
控制)可以理解成最小子進程數,而最大子進程數則由pm.max_children
去控制,OK,這樣的話,子進程數會在最大和最小數范圍中變化,還沒有完,閑置的子進程數還可以由另2個配置控制,分別是pm.min_spare_servers
和pm.max_spare_servers
,也就是閑置的子進程也可以有最小和最大的數目,而如果閑置的子進程超出了pm.max_spare_servers
,則會被殺掉。
可以看到,pm = dynamic
模式非常靈活,也通常是默認的選項。但是,dynamic
模式為了最大化地優化服務器響應,會造成更多內存使用,因為這種模式只會殺掉超出最大閑置進程數(pm.max_spare_servers
)的閑置進程,比如最大閑置進程數是30,最大進程數是50,然后網站經歷了一次訪問高峰,此時50個進程全部忙碌,0個閑置進程數,接着過了高峰期,可能沒有一個請求,於是會有50個閑置進程,但是此時php-fpm
只會殺掉20個子進程,始終剩下30個進程繼續作為閑置進程來等待請求,這可能就是為什么過了高峰期后即便請求數大量減少服務器內存使用卻也沒有大量減少,也可能是為什么有些時候重啟下服務器情況就會好很多,因為重啟后,php-fpm
的子進程數會變成最小閑置進程數,而不是之前的最大閑置進程數。
第三種 pm = ondemand
模式,這種模式和pm = dynamic
相反,把內存放在第一位,他的工作模式很簡單,每個閑置進程,在持續閑置了pm.process_idle_timeout
秒后就會被殺掉,有了這個模式,到了服務器低峰期內存自然會降下來,如果服務器長時間沒有請求,就只會有一個php-fpm
主進程,當然弊端是,遇到高峰期或者如果pm.process_idle_timeout
的值太短的話,無法避免服務器頻繁創建進程的問題,因此pm = dynamic
和pm = ondemand
誰更適合視實際情況而定。
附各參數說明:
pm string
設置進程管理器如何管理子進程。可用值:static,ondemand,dynamic。必須設置。
static - 子進程的數量是固定的(pm.max_children)。
ondemand - 進程在有需求時才產生(當請求時,與 dynamic 相反,pm.start_servers 在服務啟動時即啟動。
dynamic - 子進程的數量在下面配置的基礎上動態設置:pm.max_children,pm.start_servers,pm.min_spare_servers,pm.max_spare_servers。
pm.max_children int
pm 設置為 static 時表示創建的子進程的數量,pm 設置為 dynamic 時表示最大可創建的子進程的數量。必須設置。
該選項設置可以同時提供服務的請求數限制。類似 Apache 的 mpm_prefork 中 MaxClients 的設置和 普通PHP FastCGI中的 PHP_FCGI_CHILDREN 環境變量。
pm.start_serversin
設置啟動時創建的子進程數目。僅在 pm 設置為 dynamic 時使用。默認值:min_spare_servers + (max_spare_servers - min_spare_servers) / 2。
pm.min_spare_servers int
設置空閑服務進程的最低數目。僅在 pm 設置為 dynamic 時使用。必須設置。
pm.max_spare_servers int
設置空閑服務進程的最大數目。僅在 pm 設置為 dynamic 時使用。必須設置。
pm.max_requests int
設置每個子進程重生之前服務的請求數。對於可能存在內存泄漏的第三方模塊來說是非常有用的。如果設置為 '0' 則一直接受請求,等同於 PHP_FCGI_MAX_REQUESTS 環境變量。默認值:0。