FastCGI PHP の設定方法 と mod_php とのパフォーマンスの比較(Apache httpd)

Linux
Linux
スポンサーリンク

FastCGIとは、CGIプロセスの起動と終了にかかる手間を減らすことにより、プログラムをCGIで高速に動作させるとともに、サーバーへの負荷も少なくすることができる仕組みです。Apache httpd での FastCGI の実装 mod_fcgid により PHP を動作させると、mod_php と同じようなパフォーマンスで PHP を実行できるそうです。そこで今回は、mod_fcgid を使って FastCGI PHP を設定し、mod_php とのパフォーマンスを比較してみました。

環境

サーバーOSは CentOS7.3 (1611) です。Apache httpd 2.4 と PHP 7.1 を yum でインストールしています。

FastCGI PHP の設定

FastCGIモジュール「mod_fcgid」のインストール

Apache httpd の FastCGIモジュール「mod_fcgid」をインストールします。

yum -y install mod_fcgid

サードパーティから提供されていた FastCGIモジュール「mod_fastcgi」は、2017年9月14日現在、提供元の www.fastcgi.com のサイトに接続できなくなっています。有志の方(?)がアーカイブサイトを立ち上げていますが、今後のメンテナンスがどうなるかは不明なため、現時点では Apache httpd で FastCGI を使うには「mod_fcgid」一択になりそうです。

php-cgi のラッパースクリプトの作成

環境変数で FastCGI PHP の動作設定を指定するため php-cgi のラッパースクリプトを作成します。

vi /usr/local/bin/php-wrapper

#!/bin/sh
export PHP_FCGI_MAX_REQUESTS=10000
export PHP_FCGI_CHILDREN=0
exec /usr/bin/php-cgi

export PHP_FCGI_MAX_REQUESTS=10000
 FastCGI PHP の最大リクエスト数の設定です。初期値は500リクエストでこの回数を越えるとプロセスを再起動するため、「500 Internal Server Error」が発生することがあります。これを回避するため、PHP_FCGI_MAX_REQUESTS は大きめに設定し、Apache httpd に設定する FcgidMaxRequestsPerProcess にそれよりも小さい値を指定します。

export PHP_FCGI_CHILDREN=0
 PHPが起動する子プロセス数の設定ですが、mod_fcgid を使う場合 PHPの子プロセスを効果的に使用できないため「0」を指定して PHPが子プロセスを管理することを無効にします。

exec /usr/bin/php-cgi
 exec コマンドに続いて php-cgi の場所をフルパスで指定します。場所は「which php-cgi」で確認できます。

ラッパースクリプトのパーミッション設定

作成したラッパースクリプトのオーナーを、WEBサーバーの実行ユーザー「apache」に変更し実行権限をつけます。パーミッションが正しく設定されていない場合「500 Internal Server Error」が発生します。

chown apache /usr/local/bin/php-wrapper
chmod u+x /usr/local/bin/php-wrapper

Apache httpd の設定

mod_php を読み込まないようにします。mod_php をロードしている LoadModule〜 の行をコメントアウトしてもよいでしょう。

mv /etc/httpd/conf.modules.d/15-php.conf /etc/httpd/conf.modules.d/15-php.conf_OFF

・Apache httpd 2.4 での設定サンプルです。5行目と9〜11行目が FastCGI の設定です。
vi /etc/httpd/conf/httpd.conf

<VirtualHost *:80>
    ServerName www.example.com
    DocumentRoot "/var/www/phpapp"

    FcgidMaxRequestsPerProcess 5000
        
    <Directory "/var/www/phpapp">
        
        AddHandler fcgid-script .php
        Options FollowSymLinks ExecCGI
        FcgidWrapper /usr/local/bin/php-wrapper .php
                                
        AllowOverride None
        Require all granted
    </Directory>

    ErrorLog    logs/error_log
    CustomLog   logs/access_log combined env=!nolog
</VirtualHost>

FcgidMaxRequestsPerProcess 5000
 FastCGI アプリケーションの最大リクエスト数の設定です。初期値は0(無制限)になっています。ラッパースクリプトで指定した PHP_FCGI_MAX_REQUESTS よりも小さい値を指定します。

AddHandler fcgid-script .php
 .php 拡張子のプログラムを FastCGI(mod_fcgid)で動作させるための設定です。

Options FollowSymLinks ExecCGI
 CGIが動作するように「ExecCGI」を指定します。

FcgidWrapper /usr/local/bin/php-wrapper .php
 .php 拡張子のプログラムを先ほど作成した php-cgi のラッパースクリプト経由で実行するための設定です。

以上で FastCGI PHP の設定完了です。Apache httpd を再起動します。

systemctl restart httpd

場合によっては FastCGI PHP のタイムアウト値の調整などが必要になるかもしれません、詳しくは Apache の公式マニュアルをご参照ください。
mod_fcgid - Apache HTTP Server Version 2.5

動作確認

phpinfo関数で PHP の動作状況を出力して、Server API の行に「CGI/FastCGI」と表示されていれば FastCGI で PHP が動作していることが確認できます。
phpinfo関数の出力結果

mod_php との比較

Apache httpd で PHP を動作させるにはモジュール版の mod_php がもっとも効率がよく、サーバーへの負荷も少ないと言われています。やはり気になるのは FastCGI PHP のパフォーマンスではないでしょうか?

そこで、実際に稼働している WordPress でつくられた WEBサイト(規模:10万PV/月)を mod_php から FastCGI PHP に変更しレスポンスタイムやサーバーへの負荷の変化を確認してみました。

結論から言うと月間10万PV程度のWEBサイトであれば、mod_php と FastCGI PHP のパフォーマンスにまったく違いはありません。

WEBレスポンスタイム(First Byte)
WEBレスポンスタイムのグラフ

ロードアベレージ
ロードアベレージのグラフ

CPU負荷
CPU負荷のグラフ

メモリ使用量
メモリ使用量のグラフ

httpd プロセス数
httpdプロセス数のグラフ

PHP を FastCGI で動作させるのは危険じゃないの?

PHP を FastCGI で動作させるから危険ということはありません!

2012年「PHP-CGI の query string の処理に脆弱性JVNVU#520827(CVE-2012-1823)」の一騒ぎで、「PHP」と「CGI」というキーワードから FastCGI PHP も危険という間違った印象を持たれてしまっているようですが、そもそもこの脆弱性(CVE-2012-1823)の回避策として FastCGI PHP への移行が推奨されていました。

おわりに

最近の Apache httpd ではマルチスレッド対応の event MPM がデフォルトになっていて、パフォーマンスも良いとされています。しかしmod_php はスレッドセーフではないため prefork MPMでしか使うとこができません。(そこで FastCGI PHP の登場です)prefork MPM は HTTP/2(mod_http2)が動作しないなどの制限もあります。そろそろ event MPM への移行時期なのかもしれませんね。

コメント

  1. hyukawa より:

    いつも参考にさせていただいております。
    一つお伺いしたいのですが、
    今回の記事内容とphp-fpmを使った構成とは異なると思いますが、それぞれの位置付けと使い分けを理解できておりません。
    今度、記事にして頂けますと幸いです。

    • >hyukawaさん
      コメントありがとうございます。
      少し時間がかかるかもしれませんが、この記事の内容(mod_fcgid + php-cgi)と php-fpm との違いについてまとめてみますね。

タイトルとURLをコピーしました