1. 程式人生 > >PHP-FPM 調優:使用 ‘pm static’ 來最大化你的伺服器負載能力

PHP-FPM 調優:使用 ‘pm static’ 來最大化你的伺服器負載能力

image.png讓我們來迅速瞭解一下怎樣設定 PHP-FPM,以便達到高吞吐,低延遲以及穩定的使用 CPU 和記憶體的完美狀態。在預設的情況下,大多數設定都將 PHP-FPM PM(程序管理器)設定為 dynamic ,或者當你有可用記憶體的問題時常建議你使用 ondemand。接下來,讓我們根據 php.net 的官方文件來比較一下這兩個管理選項和我最常用的設定 —— static 之間的區別:

  • pm = dynamic:子程序的數量是根據以下指令來動態生成的:pm.max_childrenpm.start_serverspm.min_spare_serverspm.max_spare_servers
    .
  • pm = ondemand:在服務啟動的時候根據 pm.start_servers 指令生成程序,而非動態生成。
  • pm = static:子程序的數量是由 pm.max_children 指令來確定的。

檢視完整列表,深入瞭解 php-fpm.conf 的所有指令。

PHP-FPM 程序管理器(PM)和 CPUFreq Governor 的相似之處

現在,我們要說些偏離主題,但我覺得和 PHP-FPM 調優有關的事情。好了,我們都有過在某些時候的 CPU 緩慢問題,無論是膝上型電腦、VM 或者是專用的伺服器。還記得 CPU 頻率縮放問題嗎?(CPUFreq governor)這些設定在類 Unix 系統和 Windows 上是有效的,可以通過修改 CPU governor,將其從 ondemand

修改為 performance 來提高效能並加快系統的響應。現在,讓我們來比較下列 CPUFreq governor 描述和 PHP-FPM PM 有哪些相似之處:

  • Governor = ondemand:根據當前負荷動態調整 CPU 頻率。先將 CPU 頻率調整至最大,然後隨著空閒時間的增加而縮小頻率。
  • Governor = conservative:根據當前負荷動態調整頻率。比設定成 ondemand 更加緩慢。
  • Governor = performance:始終以最大頻率執行 CPU。

注意到相似之處了嗎?這就是我這個比較的首要目的,為了找到一個最好的方式來寫這篇文章,推薦你將 PHP-FPM 的 pm static

當作你的第一選擇。

使用 CPU Governor 的 performance 設定是一個非常安全的效能提升方式,因為它能完美的使用你伺服器 CPU 的全部效能。唯一需要考慮的因素就是一些諸如散熱、電池壽命(膝上型電腦)和一些由 CPU 始終保持 100% 所帶來的一些副作用。一旦設定為 performance,那麼它確實是你 CPU 最快的設定。相關例項請閱讀 'force_turbo' 在 Raspberry Pi 上的設定,它教你在 RPi 板上使用 performance Governor,由於 CPU 時鐘速度較低,效能改善將更加明顯。

使用 pm static 優化你的伺服器效能

PHP-FPM 的 static 設定取決於你伺服器有多少閒置記憶體。大多數情況下,如果你伺服器的記憶體不足,那麼 PM 設定成 ondemanddynamic 將是更好的選擇。但是,一旦你有可用的閒置記憶體,那麼把 PM 設定成 static 的最大值將減少許多 PHP 程序管理器(PM)所帶來的開銷。換句話說,你應該在沒有記憶體不足和快取壓力的情況下使用 pm.static 來設定 PHP-FPM 程序的最大數量。此外,也不能影響到 CUP 的使用和其他待處理的 PHP-FPM 操作。

file

在上面的截圖中,這臺伺服器的設定( pm = staticpm.max_children =100)最多使用了 10GB 的記憶體。請注意高亮的列。Google 分析圖中大概有 200 個活躍使用者(60秒內)。在這種使用者量下,有 70% 的 PHP-FPM 子程序被閒置。這意味著,無論當前流量如何,PHP-FPM 始終保持著足夠多的程序。閒置的程序始終保持線上,就算達到了流量的峰值也能快速響應,而不是等待 PM 生成子程序,然後在 x pm.process_idle_timeout 秒後將此程序結束。我將  pm.max_requests 設定的非常高,因為這是一個不可能發生記憶體洩漏的 PHP 生產伺服器。如果你對你的 PHP 指令碼有著 110% 的信心,那麼你可用選擇使用 pm.max_requests = 0。但建議適當的重啟服務。將請求數量設定的很高,是為了避免過高的 PM 開銷。例如,設定 pm.max_requests = 1000 ,但這需要根據 pm.max_children 的設定和實際每秒的請求數量來決定。

截圖使用  Linux top 通過 'u'(user)選項和 PHP-FPM 使用者名稱進行過濾。並只顯示了前 50 個左右(未統計)的程序,但基本上 top 命令也只會顯示適合你終端視窗大小的內容 —— 在本例中,使用 %CPU 排序。要檢視全部的 100 條 PHP-FPM 程序的話,你需要使用以下命令:

top -bn1 | grep php-fpm

何時使用 ondemand 和 dynamic

使用 pm dynamic,您可能會出現類似於下面的錯誤:

WARNING: [pool xxxx] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 32 children, there are 4 idle, and 59 total children

您可能會嘗試調整 pm 配置,但仍然會看到同樣的錯誤\在這種情況下,pm.min 太低,並且因為流量和峰值波動很大,使用 pm dynamic 可能難以調整

一般的建議是使用 pm ondemand。 然而,情況會變的更糟,因為 ondemand 會在沒有流量時關閉空閒程序,然後最終會產生與流量波動很大一樣的開銷問題 (除非您設定空閒超時的時間非常非常的長)

但是,當您擁有多個 pm 程序池時,pm dynamic, 特別是 ondemand 是可以為您節省時間的。例如在共享的 VPS 上,有 100+ 的 cPanel 賬號和 200+ 的域名,使用 pm.static 或者是 pm.dynamic 都是不可能的,即使在沒有任何流量的情況下,記憶體會被瞬間用完,而 pm.ondemand 意味著所有空閒的子程序都會被完全關閉,節省了大量記憶體。cPanel 的開發者已經意識到了這個問題,現在的 cPanel 預設就是設定為 pm.ondemand

結論

當流量波動比較大的時候,,PHP-FPM 的 ondemand 和 dynamic 會因為固有開銷而限制吞吐量。 您需要了解您的系統並設定 PHP-FPM 程序數,以匹配伺服器的最大容量。\從 pm.max_children 開始,根據 pm dynamic 或 ondemand 的最大使用情況去設定

您會注意到,在 pm static 模式下,因為您將所有內容都儲存在記憶體中,所以隨著時間的推移,流量峰值會對 CPU 造成比較小的峰值,並且您的伺服器負載和 CPU 平均值將變得更加平滑。 每個需要手動調整的 PHP-FPM 程序數的平均大小會有所不同

更新:附上一張 A/B 測試圖。

image.png