web-dev-qa-db-ja.com

単一のphp-fastcgiプロセスが他のすべてのPHPリクエストをブロックします

最近、PHP(Apache2-worker and mod_fcgid)のFastCGIセットアップに切り替えました。ただし、単一のPHPスクリプトが非常にビジー、他のすべてのPHPリクエストをブロックしているようです。私の設定の何が問題になっていますか?

mod_fcgidを使用する主な理由は、PHPメモリ使用量を制御するためです。mod_phpを使用すると、個々のApacheフォークはすべてPHPを提供した後にメモリ内で大きくなります。

また、すべてのスレッドセーフでないPHPコードがApacheの外部に存在するため、Apache2-workerモデルに切り替えました。

私のFastCGIスクリプトは次のようになります。

#!/bin/sh
#export PHPRC=/etc/php/fastcgi/
export PHP_FCGI_CHILDREN=5
export PHP_FCGI_MAX_REQUESTS=5000

global_root=/srv/www/vhosts.d/
exec /usr/bin/php-cgi5 \
-d open_basedir=$global_root:/tmp:/usr/share/php5:/var/lib/php5 \
-d disable_functions="exec,Shell_exec,system"

私のApache設定は次のようになります:

<IfModule fcgid_module>
  FcgidIPCDir /var/lib/Apache2/fcgid/
  FcgidProcessTableFile /var/lib/Apache2/fcgid/shm
  FcgidMaxProcessesPerClass 1
  FcgidInitialEnv Rails_ENV production
  FcgidIOTimeout 600
  AddHandler fcgid-script .fcgi

  FcgidConnectTimeout 20
  MaxRequestLen 16777216

  <FilesMatch "\.php$">
    AddHandler fcgid-script .php
    Options +ExecCGI
    FcgidWrapper /srv/www/cgi-bin/php5-wrapper.sh .php
  </FilesMatch>
  DirectoryIndex index.php
</IfModule>
6
vdboor

答えは次の場所にあります: https://stackoverflow.com/questions/598444/how-to-share-apc-cache-between-several-php-processes-when-running-under-fastcgi/1094068#1094068

問題はPHPではなく、mod_fcgidです。 PHPは複数の子を生成しますが、mod_fcgidはそれを認識せず、子ごとに1つのリクエストを処理します。したがって、FcgidMaxProcessesPerClass 1を使用すると、すべてPHP実行は次々に行われます。*

リンク先のソリューションは次のとおりです。 http://www.brandonturner.net/blog/2009/07/fastcgi_with_php_opcode_cache/ この制限のないmod_fastcgiの使用方法を説明しています。同じ子に複数のリクエストを送信します。

[*] FcgidMaxProcessesPerClass 1を使用しないと、PHP、Rubyなどの多くの個別のインスタンスが生成されますが、それらはすべて1つのプロセスで内部的に多くの要求を処理できます。


したがって、fastcgiでPHPを使用する新しいApache構成:

<IfModule mod_fastcgi.c>

    # Needed for for suEXEC: FastCgiWrapper On
    FastCgiConfig -idle-timeout 20 -maxClassProcesses 1 -initial-env Rails_ENV=production
    FastCgiIpcDir /var/lib/Apache2/fastcgi

    AddHandler php5-fcgi .php
    Action php5-fcgi /.fcgi-bin/php5-wrapper.sh
    DirectoryIndex index.php

    ScriptAlias /.fcgi-bin/ /srv/www/cgi-bin/
    <Location "/.fcgi-bin/php5-wrapper.sh">
        Order Deny,Allow
        Deny from All
        #Allow from all
        Allow from env=REDIRECT_STATUS
        Options ExecCGI
        SetHandler fastcgi-script
    </Location>

    # Startup PHP directly
    FastCgiServer /srv/www/cgi-bin/php5-wrapper.sh

    # Support dynamic startup
    AddHandler fastcgi-script fcg fcgi fpl
</IfModule>
3
vdboor

まず、Apacheのドキュメントが古くなっていない限り、ラッパーのスクリプトとセットアップは悪い意味でJust PlanWrongです。 mod_fcgid docs の「Special PHP考慮事項」」を読み、そこでスクリプトとサンプル設定を使用します。現在の設定では、基本的に、使用できないphp子プロセスが大量に生成されます。次に、5001番目のPHPリクエストは、5000番目のリクエストの後にPHPが終了するため、エラーになりますが、mod_fcgidに次のことを伝えるFcgidMaxRequestsPerProcess 5000ディレクティブがありません。 5000リクエスト後に新しいPHPプロセスを開始する必要があります。

同時PHPプロセスの場合、同時リクエストごとに独自のPHPプロセスが必要になるため、FcgidMaxProcessesPerClassディレクティブをより高いレベルに増やす必要があります。数。

1
DerfK