在開始前建議先去安裝 htop 這個 linux 即時監控軟體。主要因應不同的 # of process core 與 memory size,可以調整 php5-fpm 與 nginx 中兩個部分的設定。

php-fpm-with-nginx-htop.png

Nginx

在 /etc/nginx/nginx.conf 下約莫第二行有個 worker_processes 參數。

worker_processes 4;

根據運行機器的 cpu 核心數填入即可,可用 htop 或輸入以下 shell command 取得

cat /proc/cpuinfo| grep processor

PHP5-FPM

位置:/etc/php5/fpm/pool.d/www.conf
在約莫 88 行有個 pm 變數可設定 Process Manager 要以什麼型態呈現,有 static, dynamic, ondemand。

  • static: 根據 pm.max_children 所設定的值,一直固定運行這個數量的 php-fpm child process 來處理 php script 的執行需求。如一般的 process 一樣,所耗用的 memory 會隨著運行而有一定程度的增加。
  • dynamic: 根據 pm.max_children, pm.start_servers, pm.min_spare_servers, pm.max_spare_servers 這四個變數值來發揮作用。即一開始運作 php5-fpm 時就運行 pm.start_servers 數量的 child process,若沒事的 child process 就會被殺掉以維持在 pm.min_spare_servers ~ pm.max_spare_servers 的數量,因應需求最多不會產生超過 pm.max_children 的 child process 數量。通常,pm.start_servers, pm.min_spare_servers, pm.max_spare_servers 這三個參數值會是一樣。
  • ondemand: 根據 pm.max_children, pm.process_idle_timeout 這兩個參數來發揮作用。在這個模式下,一開始啟動 php5-fpm 時不會產生任何 child process,只有當有需求時才會去產生。若產生的 child process 超過 pm.process_idle_timeout 秒都沒事做的話就殺了它!

基本上 ondemand 與 dynamic 模式差不多的感覺,都是能有效 release 出 memory 供其他程式使用,但也因此在每次重新喚起新的 child process 時都會花額外的時間,不像 static 就是一直保持 child process 待命的狀態。

如何決定 pm.max_children

那至於 child process 數量要怎麼決定呢?通常一安裝 php5-fpm 時預設就是 static 搭配 pm.max_children = 32 的設定,最土法煉鋼的方式,就~運行網站個一兩天觀察一下每個 php-fpm child process 運作一段時間後需花多少 memory(如上方的 htop 截圖),即可以抓到每個 child process 所需的 memory 最大值。

如此案例,就可以抓每個 child process 大概是 1% of total memory,即約 75 MB。保險起見就抓個 100 MB 來做計算,以這台機器約 8G 的 RAM,就可以設定 pm.max_children 為 70(記得保留 1~2 G 的 quota 給其他的程式哟),或大膽一點就設定 100 XDDD

最後

那~根據最近兩三個禮拜的測試,dynamic, ondemand 固然能一直保持 memory 一直有著一定量的 free memory 供其他程式使用,維持機器處於一個較高效能的狀態,但一旦有超大需求(request)衝進來,那它是不管你三七二十一,直接就衝上所設定最高的 # of child process,很容易導致 memory 超需,機器就會爆惹.....(最近兩個禮拜就因為這樣 G 掉兩次QQ)。

因為大量需求一進來,當然你跟機器說我最大能做到那程度,它當然也就盡它所能發揮到極致,畢竟目前看起來是還沒能設定每個 php5-fpm child process 能使用的最大 memory 上限的功能,OS 似乎也沒看過有這樣的支援(窘~

所以已決定放棄追求高效能,把 pm 改回 static,追求伺服器穩定。畢竟伺服器穩穩乖乖的,我們才有好日子可以過~

續集出爐(將將將將):PHP5-FPM with Nginx 效能調教 (2)

Reference