Интенсивный скрипт PHP с ошибкой w / «Истекло время ожидания» error / ap_content_length_filter

Запуск интенсивного PHP-скрипта MySQL, который терпит неудачу. Журнал Apache сообщает об этом:

[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 

Пробовал положить set_time_limit(0) вверху.

Также попробовал set_time_limit(0)

Не был установлен тайм-аут.

Есть ли какой-то определенный лимит времени ожидания, который я могу использовать в http.conf (или в другом месте), чтобы предотвратить это?

Solutions Collecting From Web of "Интенсивный скрипт PHP с ошибкой w / «Истекло время ожидания» error / ap_content_length_filter"

Я ударил по очень похожей стене, а также с Apache 2.4.6 и PHP 5.4.23 FPM / FastCGI .

Симптом:

Независимо от того, что я установил в PHP или Apache, мой скрипт истечет через 30 секунд, и я увижу следующее в своем журнале ошибок Apache:

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

Мой 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> 

Жесткий php-скрипт:

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

Исправление: это жесткое кодированное значение в Apache mod_proxy_fcgi

Взгляните на отчет об ошибке здесь.

  • Патч доступен (ссылка выше)
  • Исправление пока не планируется для общего выпуска (март 2014)

Во-первых, мое решение применимо только к веб-серверу Apache.

Я работаю над скриптом, предназначенным для работы в качестве сценария загрузки csv для отчета с очень большим db, и я тоже столкнулся с этой проблемой. Я не использую php, но вместо этого мой скрипт написан на некоем неясном языке, называемом heitml 😉

Пробег тайм-аута запроса происходит в моем сценарии следующим образом:

 [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 

И единственным серьезным решением, с которым я могу сейчас адаптироваться, является использование этого официального расширения для тайм-аута здесь: mod_reqtimeout . Он позволяет настроить параметры таймаута, например, например:

Разрешить 10 секунд для получения запроса, включая заголовки, и 30 секунд для получения тела запроса:

 RequestReadTimeout header=10 body=30 

Разрешите получать не менее 10 секунд тела запроса. Если клиент отправляет данные, увеличьте тайм-аут на 1 секунду для каждого получаемого 1000 байтов без верхнего предела для таймаута (кроме ограничения, указанного косвенно LimitRequestBody):

 RequestReadTimeout body=10,MinRate=1000 

Разрешить не менее 10 секунд получать запрос, включая заголовки. Если клиент отправляет данные, увеличивайте тайм-аут на 1 секунду для каждого полученного 500 байтов. Но не разрешайте более 30 секунд для запроса, включая заголовки:

 RequestReadTimeout header=10-30,MinRate=500 

Обычно сервер должен иметь настроенные тайм-ауты заголовка и тела. Если общая конфигурация используется для виртуальных хостов http и https, тайм-ауты не должны быть слишком низкими:

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

Мне еще предстоит выяснить, есть ли лучшее решение, предлагаемое Apache, которое не требует от меня использования этого модуля (если он не установлен по умолчанию, хотя он включен во все версии 2.2.15 и более поздние версии).

Существует также директива php max_execution_time . Обратите внимание, что настройки тайм-аута веб-сервера также могут ограничивать ваш скрипт:

Ваш веб-сервер может иметь другие конфигурации тайм-аутов, которые также могут прерывать выполнение PHP. У Apache есть директива Timeout, а IIS – функция тайм-аута CGI. Оба по умолчанию – 300 секунд. Подробную информацию см. В документации к веб-серверу.

На самом деле это выглядит как ошибка Apache, а также эффекты скриптов Python. Вы уже пробовали его?

Я подозреваю, что получаю ту же ошибку, обновленную для более поздней версии 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 

Мне было интересно, почему увеличение max_execution_time в php.ini не работало.

Для меня исправление просто увеличивало директиву Timeout в httpd.conf https://httpd.apache.org/docs/2.4/mod/core.html#timeout

 Timeout 900 

(Или в WHM -> Apache Configuration -> Global Configuration , в зависимости от ситуации)

Этот тайм-аут применяется к времени между событиями ввода-вывода. Поэтому, даже несмотря на то, что скрипт выводил данные почти сразу, длительная задержка в середине выполнения скрипта вызывала таймаут.

Существует еще одно значение тайм-аута, размещенное не в самом php, а на сервере apache. Это будет тормозить скрипт, когда ничего не выводится на заданное время, поэтому, когда вы выполняете более сложную работу в PHP, вы можете достичь этого предела. Просто откликните все на браузер (не буферы!) Или увеличьте значение тайм-аута apache до безопасного значения, насколько я помню, это свойство ApacheAllAliveTimeOut. Удачи 🙂

Я искал эти ограничения ресурсов в php.ini, чтобы исправить проблему.

 max_execution_time = 300 max_input_time = 300 memory_limit = -1 

В php.ini также есть тайм-аут.

Примечание. Этот ответ дублируется по аналогичному вопросу .

Оригинальный ответ

У меня 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