Intensive PHP script failing w/ “The timeout specified has expired” error / ap_content_length_filter

匿名 (未验证) 提交于 2019-12-03 02:51:02

问题:

Running a MySQL intensive PHP script that is failing. Apache log reports this:

[Wed Jan 13 00:20:10 2010] [error] [client xxx.xx.xxx.xxxx] (70007) The timeout specified has expired: ap_content_length_filter: apr_bucket_read() failed, referer: http://domain.com/script.php 

Tried putting set_time_limit(0) at the top.

Also tried set_time_limit(0)

Neither fixed the timeout.

Is there some specific timeout limit I can up in http.conf (or elsewhere) to prevent this?

回答1:

I hit a very similar wall as well with Apache 2.4.6 and PHP 5.4.23 FPM/FastCGI.

Symptom:

No matter what I set in PHP or Apache, my script would timeout in 30 seconds and I would see the following in my Apache Error log:

[timestamp] [proxy_fcgi:error] [pid...] (70007)The timeout specified has expired: [client ...] AH01075: Error dispatching request to :

My VirtualHost:

TimeOut  300 KeepAliveTimeout 300  <IfModule reqtimeout_module>   RequestReadTimeout header=120-240,minrate=500   RequestReadTimeout body=120,minrate=500 </IfModule>  <IfModule mod_proxy.c>   ProxyTimeout 300 </IfModule>  <IfModule mod_fcgid.c>   FcgidConnectTimeout 300 </IfModule> 

The pesky php script:

ini_set( 'max_execution_time', '120' ); ... ini_restore( 'max_execution_time' ); 

The Fix: it's a hard coded value in Apache mod_proxy_fcgi

Take a look at the bug report here

  • A patch is available (link above)
  • The fix doesn't appear to be slated for general release yet (Mar 2014)


回答2:

I suspect I'm getting the same error, updated for a later version of Apache (2.4.16):

[Tue Aug 02 11:49:41.930884 2016] [core:error] [pid 28640] (70007)The timeout specified has expired: [client xxx.xxx.xxx.xxx:xxxxx] AH00574: ap_content_length_filter: apr_bucket_read() failed, referer: https://domain.com/script.php 

I was wondering why increasing max_execution_time in php.ini wasn't working.

For me, the fix was simply increasing the Timeout directive in httpd.conf https://httpd.apache.org/docs/2.4/mod/core.html#timeout

Timeout 900 

(Or in WHM -> Apache Configuration -> Global Configuration, as the case may be)

This timeout applies to time between IO events. So even though the script was outputting data almost immediately, a long delay in the middle of the script's execution was causing the timeout.



回答3:

First, my solution is only applicable to the Apache Web Server.

I am working on a script meant to act as a csv download script for a report against a very very large db, and I encountered this problem too. Am NOT using php, but instead my script is written in some obscure language called heitml ;-)

The request timeout proble does occur in my scenario like this:

[Wed Sep 19 20:29:01 2012] [warn] [client ::1] Timeout waiting for output from CGI script /var/www/cgi-bin/heitml [Wed Sep 19 20:29:01 2012] [error] [client ::1] (70007)The timeout specified has expired: ap_content_length_filter: apr_bucket_read() failed 

And the only serious solution I can currently adapt to is using this official timeout config extension here : mod_reqtimeout. It allows adjustment of timeout params like for example:

Allow 10 seconds to receive the request including the headers and 30 seconds for receiving the request body:

RequestReadTimeout header=10 body=30 

Allow at least 10 seconds to receive the request body. If the client sends data, increase the timeout by 1 second for every 1000 bytes received, with no upper limit for the timeout (exept for the limit given indirectly by LimitRequestBody):

RequestReadTimeout body=10,MinRate=1000 

Allow at least 10 seconds to receive the request including the headers. If the client sends data, increase the timeout by 1 second for every 500 bytes received. But do not allow more than 30 seconds for the request including the headers:

RequestReadTimeout header=10-30,MinRate=500 

Usually, a server should have both header and body timeouts configured. If a common configuration is used for http and https virtual hosts, the timeouts should not be set too low:

RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500 

Am yet to find out whether there's a better solution offered by Apache that doesn't require me to use an this module (assuming it's not installed by default -- though it's included in all versions 2.2.15 and later).



回答4:

There's also the php max_execution_time directive. Note that the web server's timeout settings may also be limiting your script:

Your web server can have other timeout configurations that may also interrupt PHP execution. Apache has a Timeout directive and IIS has a CGI timeout function. Both default to 300 seconds. See your web server documentation for specific details.

Actually, this looks like an Apache error, it also effects Python scripts. Have you tried googling it yet?



回答5:

There is another timeout value placed not in php itself but in apache server. It will brake script when nothing is on output for specified time so when doing harder work in PHP you can reach this limit. Just echo anything back to browser (not buffers!) or increase apache timeout value to safe value, as far as I remember it's KeepAliveTimeOut apache property. Good luck :)



回答6:

I played around with these resource limits in php.ini to correct the problem.

max_execution_time = 300 max_input_time = 300 memory_limit = -1 


回答7:

There is a timeout in the php.ini as well.



回答8:

Note: This answer is duplicated verbatim from a similar question.

Original Answer

I have Apache 2.4.6, but the patch to fix it is provided in Apache >= 2.4.8. The key here is to start your output immediately so that Apache (mod_proxy_fcgi) thinks the connection is active.

For example, I am using PHP and the DB query for my AJAX call takes > 30 seconds. Because I know that the overall response will be "Content-Type: application/json", I send that header immediately.

#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 


回答9:

I tried all suggestions, but my problem was in the php-fpm configuration. I set the following line in my php-fpm configuration file:

request_terminate_timeout = 300s 


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!