PHP + PHP-FPMが設定されたApache2を持っています:
http://wiki.Apache.org/httpd/PHP-FPM
内部のVhostで実行するのに長い時間がかかるスクリプトを書いていますが、タイムアウトが続くため、スクリプトが30秒未満で実行されると、すべてが問題なく実行されます。
私のApacheログは私に言っています:
[Wed Apr 17 21:57:23.075175 2013] [proxy_fcgi:error] [pid 9263:tid 140530454267648] (70007)The timeout specified has expired: [client 58.169.202.172:49017] AH01075: Error dispatching request to :, referer:
スクリプトを実行しようとすると、実行時間がちょうど30秒後に503 Service Unavailable
が与えられます。論理的には、これはタイムアウトディレクティブまたは設定を30秒に設定していることを意味しますが、仮想ホストの設定に次のように設定しています。
Timeout 600
<IfModule proxy_module>
ProxyPassMatch ^/(.*\.php)$ fcgi://127.0.0.1:9001/home/pyrokinetiq/scripts/$1 timeout=600
ProxyTimeout 600
</IfModule>
(私のためにphp-fpmがポート9001で実行されています)
また、Timeout
とProxyTimeout
をhttpd.conf
に配置してみましたが、違いはありません。
mod_proxy_fcgi
に固有のタイムアウト設定がどこかにあるようですが、見つかりません。公式のtarballからApache2 httpdをインストールしましたが、どのmodにも設定ファイルが付属していないようです。
誰かが私を正しい方向に向けることができればそれは大いに感謝されるでしょう。
いくつかの構成パラメーターをテストした後、ようやくこの問題を修正しました。ソリューションを2回テストし、以前の変更をすべて削除しました。修正するために必要なパラメーターは1つだけでした。
最新バージョンのhttpdとmod_proxy_fcgiの場合、ProxyPassMatch
行の末尾にtimeout=
を追加するだけで済みます。例:
ProxyPassMatch ^/(.+\.php.*)$ fcgi://127.0.0.1:9000/<docroot>/$1 timeout=1800
古いバージョンの場合、それは少し複雑でした、例えば:
<Proxy fcgi://127.0.0.1:9000>
ProxySet timeout=1800
</Proxy>
ProxyPassMatch ^/(.+\.php.*)$ fcgi://127.0.0.1:9000/<docroot>/$1
タイムアウトを30分に設定するには、Proxyディレクティブを追加する必要がありました。一部のアプリケーションでは、通常はデータベースを操作するときに、実行に10分以上かかるルーチンがあります。タイムアウトを30分に一時的に設定して、確実に終了するようにしました。特に時間がかかるインストールウィザードを使用する場合に便利です(私の考えでは)。
ちなみに、この問題の解決に役立った最初の入力は、次の RLアドレス で見つかりました。
この答え は古いバージョンでは問題なく動作しますが、Apache 2.4の最新バージョンではエラーコードAH00526で機能しないことを指摘しておきます。 ProxyPass
およびProxyPassMatch
または<Proxy>
および<ProxyMatch>
を同じワーカー名内で一緒に使用することはできません。これは以前はうまく機能していたので、それが設計によって変更されたかどうか、それがバグかどうかはわかりません。
どちらの方法でも、パラメータ 'timeout = 120'(または必要な値は何でも)を指定したProxyPassMatchを使用するだけでこれを修正できます。例:
ProxyPassMatch ^/(.*\.php)$ fcgi://127.0.0.1:9001/path/to/webroot/$1 timeout=120
私はApache 2.4.6を持っていますが、それを修正する patch がApache> = 2.4.8で提供されています。ここで重要なのは、出力をすぐにstartして、Apache(mod_proxy_fcgi)が接続がアクティブであると見なすようにすることです。
たとえば、私はPHPを使用しており、私のAJAX呼び出しのDBクエリには30秒以上かかります。全体的な応答は "Content-タイプ:application/json "、私はそのヘッダーをすぐに送信します。
#1: Start output immediately
#Note: Sending the header is innocuous
# it can be changed later using the $replace parameter
# (see #3)
header( 'Content-Type: application/json' );
#2: Run slow query
mysql_query( "SELECT * FROM giant_table" );
#3: Change header as needed
header( 'Content-Type: application/csv', true );
#output content
それはすべきではありません:
<IfModule mod_proxy.c>
Php.ini設定のmax_execution_timeも600に設定されていることを確認してください。 (ライブページのphpinfo()をチェックして、使用されている実際の値が表示されていることを確認してください)
ジェニーが言ったように、php-fpm設定を設定します
request_terminate_timeout 610s
(最後のsに注意してください)
Apacheのページで確認できるように、mod_proxy_fcgi自体で構成することはあまりありません。 http://httpd.Apache.org/docs/current/mod/mod_proxy_fcgi.html
Php-fpmデバッグロギングもオンにして、タイムアウトの場所を確認できるようにします。 http://php-fpm.org/wiki/Configuration_File (catch_workers_outputもオンにする)
また、Apache 2.4を使用しているため、mod_proxyおよびmod_proxy_fcgiモジュールのデバッグレベルのロギングをオンにします。とても素敵な機能、必要なモジュールだけをオンにしてください: http://httpd.Apache.org/docs/current/mod/core.html#loglevel
それでも問題が解決しない場合は、php-fpm設定ファイルを投稿してください。
最後の手段として、デーモンが長時間実行されているプロセスを殺しているのではないでしょうか?
PHP-FPMを使用していることを書き留めました。私も使用していますが、Apache 2.4.6を使用しています。
問題がしばらくの間存在していたとすると、mod_proxy_fcgi
のタイムアウト値はハードコードされているようです。見つけたものを書き留めましたここ
Apacheのタイムアウト設定を修正したので、それは問題にはなりません。 2番目に検索する場所はネットワーク機器ですが、自分のサーバーにプロキシしているので、それもありそうにありません。したがって、残りの場所はバックエンドサーバーです。
Php-pfmの構成ファイルを探して、
; This is a hard kill switch on php execution. It ignores the
; max_execution_time that can be set/changed with php_ini. Basically
; it avoids timeout issues between Apache and php-fpm.
request_terminate_timeout=30
これは、Apacheのタイムアウト設定と同じか少し下に設定する必要があります。
この投稿 は、取引全体を変更しました。
Apacheの mod_reqtimeout はデフォルト値を使用していないようです。
httpd.confファイルに次の行を追加します。
<IfModule reqtimeout_module>
RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500
</IfModule>
タイムアウトに加えて、enablereuse = offを設定します。長時間実行されているスクリプトへの一部のリクエストが正常に機能し、他のリクエストは早期に強制終了されることがわかりました。