在我們做php高並發下的優化的時候,涉及到一個問題,就是fpm進程數設置多少合適,在有的文章中推薦設置為n或者n×2(n為cpu數量)
有的文檔中推薦按照可用內存/30m (30m為fpm每個進程內存)
兩種說法其實都沒有問題,但是都忽略了一個基本的事實就是具體情況具體分析
基礎知識
需要了解的參數是:pm、pm.max_children、pm.start_servers、pm.min_spare_servers、pm.max_spare_servers。
pm:表示使用那種方式,有兩個值可以選擇,就是static(靜態)或者dynamic(動態)。
在更老一些的版本中,dynamic被稱作apache-like。這個要注意看配置文件的說明。
下面5個參數的意思分別為:
pm = dynamic 如何控制子進程,選項有static和dynamic
pm.max_children:靜態方式下開啟的php-fpm進程數量
pm.max_requests: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進程數。
在高並發場景(我們公司是一萬並發測試)中,一般都是采用的static方式,因為一般來說我們的服務器都是有嚴格的業務分離,fpm服務器就是用來作為fpm服務器使用,除去還有一個nginx之外,不會去考慮有其他的服務器占用資源。
具體問題具體分析
在php的運行中,無非是兩種場景
- 大運算
- 高io
1 大運算的場景,即 php程序需要用大量的cpu資源來進行數據計算之類的操作,在這種場景下,fpm進程可以設置為cpu數量的一倍或者兩倍
2 高io場景,php的使用場景中(最起碼是本電商場景中)基本上屬於高io,因為程序花了大量的時間在等待redis返回等待數據庫返回。高io場景下,因為cpu大多處在wa狀態下,所以可以盡量的加大fpm進程數,所以這個時候使用內存/30m是更為合理的
經過我們自己真實壓測,大量redis和mysql讀寫的io密集情況下,16G的內存,fpm我們設置為400個的時候qps比fpm 16個 32個要好不少