FastCGI環境を構築する
長らくPHP屋をやっていたのでずっとmod_phpだったんだけど、いつかはFastCGIもやらんとなぁと思っていたところに、先日Tracでmod_fcgidを導入したのでおさらいしてみる。
以下はググって自分なりにまとめたものなので、認識が間違っているものもあるかもしれないので注意。
FastCGIのメリット
- CGIプログラムのプロセスが常駐する
- プログラムの起動オーバーヘッドがない
- データやリソースをメモリ上で永続化できる(DBコネクションとか)
- Webサーバに依存しない
- suEXECできるっぽい(未調査、forkタイプだと無理?)
- ユーザ毎にプロセスが必要らしい(当然か)
FastCGIのデメリット
- プログラムをFastCGI用に書かなければいけない
- どういう作法になるかは言語による(そのまま動作する言語もある)
- ラッパーを利用すると通常のCGIプログラムをそのまま実行できる
- FCGIWrapper(mod_fcgid)
- プログラムを更新しても反映されない場合がある
- プロセスが常駐したままなので再起動する必要がある
- 言語によってまちまち(反映される、されない、インクルード類だけ反映されない、など)
- リソースリークに、より一層注意を払わなければいけない
- ハンドル
- グローバル変数
- グローバル変数の明示的な初期化が必要
- 以前の値が残っている*2
- 実行時の環境などの融通が利かない
- 環境変数
- 実行時の特別な初期化処理(ライブラリのロード時のみに走る処理など)
ApacheでFastCGIを利用するには
ApacheでFastCGIを利用する場合は、次の三種類のモジュールがある。
現在の主流はmod_fcgidっぽい。
mod_proxy_fcgiはmod_proxyみたいな感じでバックエンドのFastCGIと通信するタイプのようだ(AJPとかのイメージ)。まだ若い?
前者2つがforkなのに対して、後者は完全に独立したFastCGIプロセスと通信(TCPまたはソケット)して処理するものになるようだ。これこそがFastCGIの真の姿なんだろうか。
mod_fcgidを入れてみる
Ubuntuの場合。
sudo apt-get install libapache2_mod_fcgid sudo a2enmod fcgid
これだけ(どこかの醤油のCMみたいだ)。
設定ファイルは/etc/apache2/mods-available/fcgid.conf
最低でもhttp://fastcgi.coremail.cn/doc.htmを見て、MaxProcessCount、DefaultMinClassProcessCount、DefaultMaxClassProcessCountあたりは調整しておきたい。ついでにApache MPMのほうも調整しておいたほうがいい。
この辺をしっかり調整しないと処理をさばききれなくてリクエストが失敗するようになる。
デスクトップPCのバーチャルマシンみたいなリソースの乏しい環境で、テストがてらにabでも回そうものなら大変なことになる。
PHPをFastCGIで動かす
PHPは他の言語とは少し違った動きをするようだ。
多くの言語がコンパイル済みプログラムをそのままプロセスに残すのに対し、PHPはインタプリタだけを残してスクリプト自体は毎回コンパイルするらしい*3。
毎回コンパイルするオーバーヘッドが生じるけど、反面スクリプトファイルを書き換えると即座に反映されることになる。他の言語の場合はプロセスを再起動する必要があるが、mod_fcgidの場合、つまるところApacheを再起動することになるので結構痛い。
PHPはmod_phpの使い勝手そのままという感じか*4。というかPHPにおけるFastCGIはmod_phpと大差ない気がしてきた。
設定には一工夫必要で、FCGIWrapperにCGI版のPHPインタプリタを指定する。
<Directory /var/www/php-fcgi> AddHandler fcgid-script .php FCGIWrapper /usr/bin/php-cgi .php Options +ExecCGI </Directory>
スクリプトファイル側はShebang(#!/usr/bin/phpとかいうやつ)は必要ない。というか付けるとそのまま出力されるっぽい。
ただしパーミッションは実行権限を付けておく必要がある。
その他のこと
SpeedyCGIとか。