Apache + mod_fastcgi + php-fpm 設定

前言

這篇是有人叫我分享的 , 順便測一下 php-fpm 和 Apache 搭配起來的效能及穩定度 , 由於 php-fpm 是自帶的 FastCGI Process Manager , 所以和原本的 php fastcgi 有所不同 , php-fpm 若要搭配 Apache 只能以 mod_fastcgi 來運作 , 原本 Apache 有開發 mod_fcgid , 但 mod_fcgid 本身算是個 FastCGI Process Manager , 只能執行本地端 FastCGI , 而 php-fpm 可以用 Unix Socket 或 TCP 模式讓任何具備執行外部 FastCGI 程序的 WebServer 連接 , 因此 lighttpd 或 Ngix 等都可以 , 唯獨世上次爛的 Apache 要外掛 mod_fastcgi , 最爛的當然是 IIS 了 , 哈 ...

運作環境

  • CentOS 5.5 64bit 及內建的 Apache 2.2 套件
  • PHP 5.3.3 , 此版本有內建 php-fpm 了 , 過去的版本皆須 patch 才有 php-fpm
  • 硬體 : Core I5 4 核心的 , RAM 2GB

準備工作

1. 確認以下套件是否安裝

httpd-devel.x86_64

php-5.3.3 , 可由 remi 的 yum 升級 , 不知道的請看

https://www.pigo.idv.tw/archives/242

php-fpm , 直接由 remi 安裝 , 例如 yum --enablerepo=remi install php-fpm

2. 安裝 mod_fastcgi

由於 CentOS 是沒有提供 mod_fastcgi , 因此要自己下載原始碼來編譯 , 其他的 Linux 套件也許早就有包好了 , 像 Ubuntu Server 就有包 , 所以用其他套 Linux 的人未必要自己編譯ˋ

接下來從 http://www.fastcgi.com/dist/ 下載 mod_fastcgi-x.x.x.tar.gz 的原始碼下載回來 , 解開原始碼進入解開的目錄後 , 按照下面步驟編譯及安裝即可

cp Makefile.AP2 Makefile
make top_dir=/usr/lib/httpd
make install top_dir=/usr/lib/httpd

這種安裝法為原始碼中 INSTALL.AP2 所記載的 , 若安裝成功 , 應該會在 /etc/httpd/modules/ 下看見 mod_fastcgi.so , 如果是 64bit 系統 , 上述的 top_dir 要改為 /usr/lib64/httpd

 

修改為最佳運作環境的設定

1. Apache 改為 worker 模式運作

甚麼是 worker 模式 ? 簡單來說就是 Apache 會搭配多行程+多執行緒的方式運作 , 每個行程會有多個執行續同時服務客戶端連線 , 記憶體及效能都較好 , 由於 php-fpm 或 php fastcgi 都已經是獨立於 Apache 行程了 , 所以 Apache 若再跑 prefork 模式就浪費了 , 因此可以切換為 worker 模式 , 在 CentOS 下切換很簡單 , 只要修改 /etc/sysconfig/httpd

原本有一行註解

#HTTPD=/usr/sbin/httpd.worker

把 # 註解拿掉即可了

2. 修改 /etc/php-fpm.d/www.conf

此檔為預設的設定檔 , 大部分參數是不用改了 , 因為預設幾乎都不設限 , 唯獨要把 listen 改成 unix socket 來接受連線

原本有一行 listen = 127.0.0.1:9000 , 只要加個註解 , 新增一行改成如下就可以

;listen = 127.0.0.1:9000
listen = /tmp/php-fpm-www.sock
 

3. 增加 mod_fastcgi 在 Apache 的設定檔

之前有安裝好 mod_fastcgi , 但安裝好後 , Apache 是不會載入 mod_fastcgi 模組的 , 所以可以另外寫個檔案在 /etc/httpd/conf.d/mod_fastcgi.conf , 裡頭只要寫一行如下即可

LoadModule fastcgi_module modules/mod_fastcgi.so

4. 修改 /etc/httpd/conf.d/php.conf

原本預設的 php.conf 是單給 mod_php 運作方式使用的 , 所以我有另外修改為 prefork + mod_php 及 worker + fastcgi 的設定方便切換  , 我將內容貼上

<IfModule prefork.c>
  LoadModule php5_module modules/libphp5.so
  AddHandler php5-script .php
  AddType text/html .php
</IfModule>
<IfModule worker.c>
  FastCGIExternalServer /php-fpm-handler -socket /tmp/php-fpm-www.sock
  AddHandler php-fastcgi .php
  Action php-fastcgi /php-fpm-handler.fcgi
  ScriptAlias /php-fpm-handler.fcgi /php-fpm-handler
</IfModule>
DirectoryIndex index.php

這個設定檔會判斷 Apache 是 prefork 或 worker 模式運作 , 如果是 prefork 就是用 mod_php 的傳統方式跑 php , 如果是 worker , 就會用 fastcgi + php-fpm 方式來運作

5. 最後

都設定完成後 , 重啟 Apache ( /etc/rc.d/init.d/httpd restart ) 及執行 /etc/rc.d/init.d/php-fpm start

注意 : php-fpm 套件有安裝一個服務啟動檔就是 /etc/rc.d/init.d/php-fpm , 因此可以設定 php-fpm 這個服務開機時啟用

測試心得

隨便寫個 <?php echo "hello world"; ?> 來測試

我用 ab -c xx -n xxxx 的方式來測試效能及穩定度 , 分別用 20 , 100 , 500 條連線來測試 50000 次 request

大概可以直接說結果 , 就不看數據了

在 20 及 100 條連線下 , mod_php 的執行時間大約在 3~4 秒 , php-fpm 則在 7~8 秒 , 看樣子 php-fpm 挺鳥的說 ~~

但 500 條連線就見真章了 , mod_php 會很不穩 , 中間會 lag , 所以測試的數據忽上忽下 , 有時 7 秒 , 有時 10 秒甚至 15 秒

而 php-fpm 仍然在 7~8 秒 , 非常穩定

這代表甚麼 ????

Apache worker 模式 + php-fpm 在一個連線數量很多很操的 Server 上會表現得很穩定 , 另外我要說一下 , mod_fastcgi 其實效能並不佳 , 很多測試數據都有說比 Apache 自己寫的 mod_fcgid 差很多 , 我自己也玩過 mod_fcgid + php 也是如此  , 但 mod_fastcgi 表現卻比較穩定 , mod_fcgid 在連線數量多及連續 request 次數多時也會有 lag 情形 ,  因此, 有興趣尋求最佳php運作環境的人的可以試試看 lighttpd 或 ngix 甚至是號稱比 lighttpd 及 ngix 快很多的 cherokee 來搭配 php-fpm , 應該會有更棒的表現

後來想想 , hello world 在傳輸的數據太少 , 於是再多測試 <?php phpinfo(); ?> 這個方式

也是用 20 /100/500 條連線來 request 1 萬次

20 條連線時 , mod_php 最佳時間為 6.45 秒 , 而 php-fpm 為 6.42 秒 , 差不多 , 而且都不會 lag

100 條連線時 , mod_php 最佳時間為 6.43 秒 ,php-fpm 為 6.37 秒 , 還是差不多 , 而且都不會 lag

500 條連線時 , mod_php 最佳時間為 6.69 秒 , php-fpm 為 6.42 秒 , 看起來還是一樣 , 但 500 條連線時 , mod_php 發生 lag 情形較多次 , 也就是說可能會看到超過 10 秒以上的時間挺多次的

從上面的測試不難發現 , Apache fork 模式的架構仍有一定的瓶頸 , 而且在實際網站應用上不光只有 php , 還有其他的靜態網頁 , 如果使用 Apache+mod
_php 跑 , 這樣靜態網頁的效能會跟著被拖慢 , 而 Apache worker + php-fpm (或 php fastcgi) 的好處是 , Apache 只把 php 的處理權交出去 , 靜態網頁仍由 Apache 處理 , 這樣在整體效能及記憶體用量都會改善許多

若以單項只跑 php 來看 , mod_php 在一個人不多的網站其實是最快的 , 但當流量大到一定程度 , 除非多買硬體啦 , 若要節省成本 , 採用 FastCGI 架構才是最好的方式

補充一下 : lighttpd + php-fpm 同樣方式測的時間是 5.95/5.96/6.01 秒 , 快很多吧 ^^

後記

PHP 5.3 之後新增了 user ini 的設定 , 在 5.3 版本之前我們為了要讓不同的 Virtual Host 或目錄有不同的 php.ini 設定 , 在 mod_php 模式中可以在 Apache 設定檔或 .htaccess 直接指定 php_value 或php_flag 等等的設定 , 但在 FastCGI 模式下是不行的 , 除非在 FastCGI 設定中另行指定 php.ini 路徑 , 而 PHP 5.3 之後的 user ini 設定就很方便了 , 只要在 php.ini 中打開 user_ini.filename = ".user.ini" , 然後在 PHP 應用程式的目錄下新增一個 .user.ini , 就可以直接單獨設定該 PHP 應用程式所需的項目。

當然 php-fpm 也可以用自己的設定檔也可以作類似的效果 。

1 則評論在 Apache + mod_fastcgi + php-fpm 設定.

  1. 通告: Install Mod-FastCGI and PHP5-FPM on Ubuntu » Starck Lin

發佈留言