apacheのfcgidをインストールしましょう
apacheのFastCGIのためのモジュールは、2つあります。
- fastcgi ( mod_fastcgi )
– MTMで動作させた場合に問題があるといわれている
- fcgid ( mod_fcgid )
– 後発のFastCGIモジュールで、mod_fastcgiより高速で、mod_fastcgiの問題点を改善したといわれている
ここでは、速そうなfcgid ( mod_fcgid )をインストールしてみます。
CentOSなのでyumで簡単にインストールできます。
$ yum install mod_fcgid
Loaded plugins: downloadonly, fastestmirror
...
Installed:
mod_fcgid.i386 0:2.2-11.el5
Complete!
$
|
と、こんな感じです。
インストールするとapacheのモジュール設定ファイル( /etc/httpd/conf.d/fcgid.conf )が自動的に作成されます。
# This is the Apache server configuration file for providing FastCGI support
# through mod_fcgid
#
# Documentation is available at http://fastcgi.coremail.cn/doc.htm
LoadModule fcgid_module modules/mod_fcgid.so
# Use FastCGI to process .fcg .fcgi & .fpl scripts
# Don't do this if mod_fastcgi is present, as it will try to do the same thing
<IfModule !mod_fastcgi.c>
AddHandler fcgid-script fcg fcgi fpl
</IfModule>
# Sane place to put sockets and shared memory file
SocketPath /var/run/mod_fcgid
SharememPath /var/run/mod_fcgid/fcgid_shm
|
これについては、何も変更の必要はないと思います。
最新バージョンでは、パラメータ(ディレクティブ)名が変更になっています。
# This is the Apache server configuration file for providing FastCGI support
# through mod_fcgid
#
# Documentation is available at
# http://httpd.apache.org/mod_fcgid/mod/mod_fcgid.html
LoadModule fcgid_module modules/mod_fcgid.so
# Use FastCGI to process .fcg .fcgi & .fpl scripts
AddHandler fcgid-script fcg fcgi fpl
# Sane place to put sockets and shared memory file
FcgidIPCDir /var/run/mod_fcgid
FcgidProcessTableFile /var/run/mod_fcgid/fcgid_shm
|
変更前 | 変更後 |
SocketPath | FcgidIPCDir |
SharememPath | FcgidProcessTableFile |
MaxRequestsPerProcess | FcgidMaxRequestsPerProcess |
apacheの仮想ホストでfcgidを使用するように設定しましょう
続けて、仮想ホストの設定 ( /etc/httpd/conf/httpd.conf ) を編集します。
例として、前回の「apache で phpのモジュール版とcgi版の切り替えを行ってみる」で使った、example.com を編集してみましょう。
<VirtualHost *:80>
ServerName example.com
DocumentRoot "/home/example"
ServerAlias www.example.com
<Directory "/home/example">
Options FollowSymLinks Includes ExecCGI
AddHandler fcgid-script .php
FCGIWrapper /var/www/cgi-bin/php52 .php
AllowOverride None
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
|
赤部分を追記すればOKです。
最初は、.php の拡張子 に対応した ハンドラをfcgidとします。
次は、.php の拡張子 に対応した CGI実行ファイルのパス(フルパス)を設定しています。
ここでは、フルパスを設定できますので、
/var/www/cgi-bin/php52 → /usr/bin/php-cgi
のように設定してもOKです。
最後にapacheを再起動でします。
$ /etc/init.d/httpd restart
httpd を停止中: [ OK ]
httpd を起動中: [ OK ]
$
|
FastCGI( fcgid )を使用してみましょう
まずは、apacheが起動したphp-cgiがあるか確認します。
$ ps aux | grep php
root 7805 0.0 0.2 5072 776 pts/5 R+ 08:20 0:00 grep php
$
|
・・・と、apacheを再起動しただけなら、上記のように何のプロセスも動作してないのがわかります。
次に、wgetでphpファイルをアクセスしてみましょう。
例でいけば、http://www.example.com/info.php をwgetでアクセスすればOKになります。
$ wget http://www.example.com/info.php
--2011-05-19 10:54:00-- http://www.example.com/info.php
www.example.com をDNSに問いあわせています... 192.168.219.100
www.example.com|xxx.xxx.xxx.xxx|:80 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 特定できません [text/html]
`info.php` に保存中
[ <=> ] 76,878 --.-K/s 時間 0.001s
2011-05-19 10:54:00 (16.6 MB/s) - `info.php` へ保存終了 [76878]
$
|
・・・と、正常にアクセスできたら、phpのプロセスを確認してみましょう。
$ ps aux | grep php
apache 7760 0.0 3.0 158712 9628 ? S 08:13 0:00 /usr/bin/php-cgi
root 7795 0.0 0.2 5072 776 pts/5 R+ 08:20 0:00 grep php
|
・・・と、/usr/bin/php-cgi のプロセスが動いてます。
プロセスが、ある程度の要求処理をはいてしまうまで、そのままphp-cgiプロセスが生きたままになります。
これが、FastCGIの特徴です。
suEXECで実行しているなら、
php-cgi のプロセス所有者は、suEXECの実行ユーザになります。
ざっと、こんな感じですね。
FastCGIは、動作させるだけなら、簡単です。
ただ、PHPでは、APCなどとの競合やPHPの子プロセス管理について考え始めると、ちょっと大変になってきます。
apache のsuEXEC で phpを動かしてみるで説明したように
php-cgi を動作させるためのスクリプトを設置する場合、よくある例が、以下のような感じです。
#!/bin/sh
PHPRC=/etc/
export PHPRC
export PHP_FCGI_MAX_REQUESTS=5000
export PHP_FCGI_CHILDREN=8
exec /usr/bin/php-cgi
|
ここの各々のパラメータの意味は、以下のとおりです。
PHP_FCGI_MAX_REQUESTS : 指定された要求を処理するまでプロセス数
PHP_FCGI_CHILDREN : 同時起動する子プロセス数
これだと1つのphpを起動すると一気に8つの子プロセスが起動され、その8つのプロセスが5000件処理するまで終了しません。終了した場合は、次回の要求時に自動でphp-cgiのプロセスを再起動します。
(apacheを停止したら、php-cgiのプロセスは全て終了します。)
PHPの場合、どうしてもメモリが膨れ上がりすぎたり、リークの危険性をぬぐえませんから、このようにある程度処理したら、プロセスを入れ替えてあげる必要があるんですね。
FcgidMaxRequestsPerProcess
FcgidMaxRequestsPerProcessは、
mod_fcgidのパラメータで、1つのphp-cgiのプロセスが、どのくらい要求処理をしたら終了させるかというものです。
また、PHP_FCGI_MAX_REQUESTSは、
php-cgiのパラメータで、これもphp-cgi自身がどのくらいまで処理をするかを指定するものです。(何も指定しない場合は、500件まで処理して、終了します。)
ここで問題が発生することがあります。PHP_FCGI_MAX_REQUESTSを超えた処理を要求した場合、php-cgiは、超えたと判断したら、処理を無条件に終了します。つまり、500,503 のエラーを出力する場合があります。
それを回避するために、FcgidMaxRequestsPerProcessにPHP_FCGI_MAX_REQUESTSの数値以下の数字を指定することで回避することが推奨されています。
この要求数を無駄なリソースなく効率的に処理させるためには、子プロセスを使うべきではないとされています。
mod_fcgidを利用する場合、PHP_FCGI_CHILDREN=0で子プロセスを無効にしなさいと言われるのは、このためです。
さらに、子プロセスを使えないことから、mod_fcgidは、APC(PHPのメモリキャッシュ機能)が有効活用できないという問題を含んでいます。
FastCGIと通常のCGIの処理速度の差は、どんなものだったか?
同じものをwgetで単純な計測を行った結果、
FastCGI : 0.001s
通常CGI : 0.004s
でした。
おおよそ10回やってみましたが、ほとんど変わりませんでした。
通常CGIでは、毎回、php-cgiのプロセスを起動しているようなものです。
それに対して、
FastCGI(mod_fcgid)は、初回こそ、php-cgiのプロセスを起動しますが、以降しばらくは、同じプロセスを利用します。
そのことからも、この差は、当然のような気がしますね。
さあ、この結果をどう見ますか?
2012年12月12日, 11:10 PM
[…] こちらのブログが参考になるかと思います。 apache の FastCGI(mod_fcgid) で phpを動かしてみる | レンタルサーバー・自宅サー… Apacheをマルチスレッド(worker)環境にしてPHP(CGI/FastCGI)を動かす – […]
2014年5月28日, 1:47 PM
会社のサーバーにapcと同時にmod_fcgidを導入してみました。
apcのキャッシュがすぐクリアされる現象になやまされていましたら・・・。
>さらに、子プロセスを使えないことから、mod_fcgidは、APC(PHPのメモリキャッシュ機能)が有効活用できないという問題を含んでいます。
なるほど!!
納得いきました。
自分のサーバーで検証してみましたら、php5.5のOPcacheだった・・・。