Apache2代理超时


23

我有根据以下配置配置的具有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:

尝试运行脚本时503 Service Unavailable,恰好在30秒的执行时间后给出了a 。从逻辑上讲,这意味着我将超时指令或设置设置为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端口上运行)

我也曾尝试放置Timeout,并ProxyTimeouthttpd.conf与无差异。

似乎还有一个特定于的超时设置mod_proxy_fcgi,但我找不到。我从官方tarball安装了Apache2 httpd,似乎所有mod均未附带任何配置文件。

如果有人能指出我正确的方向,将不胜感激。

Answers:


32

在测试了几个配置参数之后,我终于解决了这个问题。我对解决方案进行了两次测试,删除了之前的所有更改。我只需要一个参数即可修复它。

对于最新版本的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 / <Proxy>和ProxyPassMatch / <ProxyMatch>不能与相同的工作人员名称一起使用
Stewart Adam

4
我已经通过在ProxyPassMatch行的末尾添加参数'timeout = 120'解决了上述问题。
斯图尔特·亚当

@Palantir很高兴听到它!提交为答案
斯图尔特·亚当

我还需要做两件事:首先,必须在全局apache配置文件中将“超时”和“ 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 / ...
Falken教授

9

我想指出的是,尽管此答案对较旧的版本非常有效,但它在Apache 2.4的最新版本下却出现错误代码AH00526。ProxyPassProxyPassMatch<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调用的数据库查询需要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

(请注意末尾的)

正如您可以在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中修复了音色设置,因此这不是问题。第二个要看的地方是任何网络设备,但是由于您要代理自己的服务器,因此也不大可能。因此,剩下的地方是后端服务器。

Ih的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_timeout为400,但仍然没有更改:(我觉得我需要设置一些东西mod_proxy_fcgi,但是似乎没有任何配置文件
。– wyqydsyq

0

除超时外,还设置enablereuse = off。我发现,在某些要求长时间运行的脚本的请求下,它可以正常工作,而其他请求则可能会提前被杀死。


0

这篇文章改变了我的整个工作。

看来Apache 的mod_reqtimeout不会使用默认值。

将以下行添加到您的httpd.conf文件中:

<IfModule reqtimeout_module>
  RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500
</IfModule>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.