Codeigniter搭配Apache及PHP-FPM

最近想將使用CodeIgniter這套php framework的系統改用PHP: FastCGI Process Manager (FPM)運行。

由於採用了CodeIgnite官方CodeIgniter URLs : CodeIgniter User Guide的作法,於網址中移除index.php。因此,當設定好PHP-FPM後,尚須處理移除index.php這段設定。

另外,也由於apache的版本演進,不同版本配合PHP-FPM的設定方式也有所不同,找資料過程中看過很多種設定。因此把最後採用的設定方式做個紀錄。

以下的設定則是在Apache 2.4.25,採用Handler方式、搭配mod_proxy_fcgi的紀錄。
註:以下Apache設定方式,版本必須為 2.4.10 以上

首先,在httpd.conf做設定
#能對應到檔案、目錄。如沒這行,後面Handler的設定,就需要指定目錄
<Proxy "fcgi://localhost/" enablereuse=on max=10>
</proxy>
<FilesMatch "\.php$">
#這之前為了動態服務(Dynamic serving)設定。和php-fpm無關
Header append Vary User-Agent env=!dont-vary
#藉由Handler,將php轉給php-pfm
SetHandler "proxy:fcgi://127.0.0.1:9000/"
#前面如果沒有設定 proxy,此處就要指定index.php檔案所在位置
#SetHandler "proxy:fcgi://127.0.0.1:9000/codepath/index.php"
</FilesMatch>

接者調整.htaccess
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www\.test\.com)$ [NC]
RewriteCond $1 !^(robots\.txt|favicon\.ico|index\.php|google[\w]+\.html|BingSiteAuth\.xml|apple-touch-icon[-\w]*\.png|crossdomain\.xml)
#注意,index.php後面必須有問號(?)
RewriteRule ^(.*)$ /index.php?/$1 [L]
如果沒有這個問號,網頁上會出現
File not found.

為了瞭解為何這樣,以瀏覽 http://www.test.com/controller/function/ 這網址為例,搭配PHP-FPM的access log,可看出這設定的差異
#使用index.php/$1 的log
127.0.0.1 - 24/Apr/2017:01:38:12 +0800 "GET /controller/function/" 404 - 3.694 256 211.49%
#使用index.php?/$1 的log
127.0.0.1 - 24/Apr/2017:01:38:45 +0800 "GET /index.php?/controller/function/" 200 //codepath/index.php 1844.802 2304 15.25%

設定成功後,使用ab - Apache HTTP server benchmarking tool做個簡單測試以瞭解PHP-FPM對於效能的改善狀況。以下,分別對於兩種不同資料來源的程式進行多次測試後的結果…
  1. 資料來源為資料庫的網頁,Requests per second 平均提升25%
  2. 資料來源為Redis的網頁,Requests per second 平均提升61%
最後提一下… 雖然官方文章-mod_proxy_fcgi - Apache HTTP Server Version 2.4提到可以使用unix domain socket (UDS)模式。但在我的測試VM中卻一直無法成功…看來,要在找公司內的系統高手來協助了~ :D


參考資料

留言