Apache2プロキシタイムアウト


23

私は、Apache2とPHP + PHP-FPMを次のように構成しています。

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:

スクリプトを実行しようとすると、503 Service Unavailableちょうど30秒の実行時間が経過します。論理的には、これはタイムアウトディレクティブまたは設定が30秒に設定されていることを意味しますが、Vhostの構成には次のようなものがあります。

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で実行されています)

私はまた、配置しようとしているTimeoutProxyTimeouthttpd.conf違いはありませんで。

に固有の別のタイムアウト設定があるようですがmod_proxy_fcgi、見つけることができません。公式のtarballからApache2 httpdをインストールしましたが、どのmodにも構成ファイルが付属していないようです。

誰かが私を正しい方向に向けることができれば、それは大歓迎です。

回答:


32

いくつかの構成パラメーターをテストした後、最終的にこの問題を修正しました。ソリューションを2回テストし、以前の変更をすべて削除しました。修正するのに必要なパラメーターは1つだけです。

httpdとmod_proxy_fcgiの最新バージョンでtimeout=は、ProxyPassMatch行の最後に追加するだけです。例えば:

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

Proxyディレクティブを追加して、タイムアウトを30分に設定する必要がありました。一部のアプリケーションでは、通常データベースを操作するときに、実行に10分以上かかるルーチンがあります。確実に終了するために、一時的にタイムアウトを30分に設定しました。インストールウィザードを使用するときに特に便利です。これには時間がかかりすぎます(謙虚な意見です)。

ところで、この問題を解決するのに役立った初期の入力は、次のURLアドレスで見つかりました。


1
これは、Apache、AH00526の最近のバージョンで破ったように見えます:はProxyPass / <プロキシ>とProxyPassMatch / <ProxyMatch>同じワーカー名で完全に使用することはできません
スチュワートアダム

4
ProxyPassMatch行の最後にパラメーター 'timeout = 120'を追加することで上記を解決しました。
スチュワートアダム

@Palantirそれを聞いてうれしい!回答として提出されました
スチュワートアダム

さらに2つの必要なものがあります。まず、グローバルApache構成ファイルの「Timeout」と「ProxyTimeout」を他のFPMタイムアウトよりも長く設定する必要があります。次に、私のFPMプールはUNIXソケットでリッスンしていたので、次のようにSetHandlerを使用します。[SetHandler "proxy:unix:/var/run/php/example.com-php7.0-fpm.sock | fcgi:// localhost: 8000 "]。しかし、<Proxy>はSetHandler行のfcgi:// localhost部分(実際には使用されていない| ...の後の部分!)で一致し、unix:/ var / run /部分では一致しません。したがって、上記の使用のためにタイムアウトを設定するには:<Proxy fcgi:// localhost:8000>ではなく<Proxy unix:/ var / run / ...
教授ファルケン

9

この答えは古いバージョンではうまく機能しますが、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

6

Apache 2.4.6を使用していますが、それを修正するパッチはApache> = 2.4.8で提供されています。ここで重要なのは、Apache(mod_proxy_fcgi)が接続がアクティブであると判断できるように、すぐに出力を開始することです。

たとえば、PHPを使用しており、AJAX呼び出しのDBクエリに30秒以上かかります。全体的な応答が「Content-Type: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

2

それはすべきではありません:

<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構成ファイルを投稿してください。

最後の手段として、おそらくいくつかのデーモンが長時間実行されているプロセスを殺していますか?


2

PHP-FPMを使用していることに注意しました。私も使用していますが、Apache 2.4.6を使用しています。

問題がしばらく存在していると仮定すると、タイムアウト値mod_proxy_fcgiハードコードされているようです。ここで見つけたことを書きまし


1

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のタイムアウト設定と同じか、それより少し下に設定する必要があります。


1
request_terminate_timeout400に設定しましたが、まだ変更はありません:(設定する必要があるものがあると感じていmod_proxy_fcgiますが、構成ファイルが付属していないようです。
wyqydsyq13年

0

タイムアウトに加えて、enablereuse = offを設定します。長時間実行されているスクリプトへの要求が正常に機能し、他の要求が早期に終了することがわかった。


0

この投稿は私にとって全体の取引を変えました。

Apache のmod_reqtimeoutはデフォルト値を使用していないようです。

httpd.confファイルに次の行を追加します。

<IfModule reqtimeout_module>
  RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500
</IfModule>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.