我有 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 上运行)
我也尝试过放置Timeout
和ProxyTimeout
,没有httpd.conf
任何区别。
似乎在某个地方有另一个特定于 的超时设置mod_proxy_fcgi
,但我找不到它。我从官方 tarball 安装了 Apache2 httpd,似乎没有任何 mods 附带任何配置文件。
如果有人能给我指明正确的方向,我将不胜感激。
答案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
我需要添加代理指令以将超时设置为 30 分钟。在某些应用程序中,通常是在操作数据库时,有些例程可能需要超过 10 分钟才能执行。我暂时将超时设置为 30 分钟以确保它们完成。在使用安装向导时特别有用,因为这需要太多时间(我个人认为)。
顺便说一下,帮助我解决这个问题的初始输入是在以下内容中发现的URL 地址。
答案2
我想指出的是,尽管这个答案在旧版本上效果很好,但在最新版本的 Apache 2.4 下会崩溃,错误代码为 AH00526。andProxyPass
或ProxyPassMatch
and不能在同一个 worker 名称中一起使用。以前这个功能很好,所以不知道这是设计上的改动还是一个 bug。<Proxy>
<ProxyMatch>
无论哪种方式,您都可以通过使用带有参数“timeout = 120”(或您想要的任何值)的 ProxyPassMatch 来解决此问题,例如:
ProxyPassMatch ^/(.*\.php)$ fcgi://127.0.0.1:9001/path/to/webroot/$1 timeout=120
答案3
我有 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
答案4
我注意到您正在使用 PHP-FPM。我也使用它,但使用的是 Apache 2.4.6。
假设该问题已经存在了一段时间,则超时值似乎mod_proxy_fcgi
是硬编码.我写下了我的发现这里