Тайм-аут прокси-сервера 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 для меня)

Я также попытался поместить Timeoutи ProxyTimeoutв httpd.confбез разницы.

Кажется, есть другое время ожидания где-то определенное mod_proxy_fcgi, но я не могу его найти. Я установил Apache2 httpd из официального архива, кажется, что ни один из модов не поставляется с какими-либо конфигурационными файлами.

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

wyqydsyq
источник

Ответы:

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> не могут использоваться вместе с одним и тем же рабочим именем
Стюарт Адам
4
Я решил вышеупомянутое, добавив параметр «timeout = 120» в конце строки ProxyPassMatch.
Стюарт Адам
@Palantir рад это слышать! Представлено как ответ .
Стюарт Адам
Еще две вещи, которые мне нужны: во-первых, вы должны установить «Timeout» и «ProxyTimeout» в вашем глобальном конфигурационном файле apache так, чтобы они были длиннее, чем другие тайм-ауты FPM. Во-вторых, мой пул FPM прослушивал сокет unix, и я использую SetHandler следующим образом: [SetHandler "proxy: unix: /var/run/php/example.com-php7.0-fpm.sock | fcgi: // localhost: 8000 "]. Но <Proxy> соответствует в части fcgi: // localhost строки SetHandler (часть ПОСЛЕ | ..., которая даже не используется!), А НЕ в unix: / var / run / part. поэтому для настройки времени ожидания для вышеприведенного использования: <Proxy fcgi: // localhost: 8000>, а не <Proxy unix: / var / run / ...
Профессор Фалькен,
9

Я хотел отметить, что хотя этот ответ отлично работает для более старых версий, он ломается в последних версиях Apache 2.4 с кодом ошибки AH00526. ProxyPassи ProxyPassMatchили <Proxy>и <ProxyMatch>не могут использоваться вместе в пределах одного и того же имени работника. Раньше все работало нормально, поэтому не знаю, было ли это изменено в дизайне или это ошибка.

В любом случае вы можете исправить это, используя только ProxyPassMatch с параметром timeout = 120 (или любым другим желаемым значением), например:

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

(обратите внимание на s в конце)

Там не так много, чтобы настроить с самим mod_proxy_fcgi, как вы можете видеть на странице apache. http://httpd.apache.org/docs/current/mod/mod_proxy_fcgi.html

Также включите ведение журнала отладки php-fpm, чтобы вы могли видеть, где оно истекло. http://php-fpm.org/wiki/Configuration_File (также включите catch_workers_output)

И включите ведение журнала уровня отладки для модулей mod_proxy и mod_proxy_fcgi, так как вы используете apache 2.4. Очень хорошая функция, включите только те модули, которые вам нужны: http://httpd.apache.org/docs/current/mod/core.html#loglevel

Если это не помогло, опубликуйте свой конфигурационный файл php-fpm.

В крайнем случае, может быть, какой-нибудь демон убивает длительный процесс?

troseman
источник
2

Я заметил, что вы используете PHP-FPM. Я тоже им пользуюсь, но с Apache 2.4.6.

Если предположить , что проблема существует в течение некоторого времени, это , кажется , что значение тайм - аута для mod_proxy_fcgiбудет жёстко . Я написал то, что я нашел здесь

misterich
источник
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. Я обнаружил, что при выполнении некоторых запросов долго выполняющиеся сценарии будут работать правильно, а другие будут убиты рано.

ctlq
источник
0

Этот пост изменил всю сделку для меня.

Похоже, что mod_reqtimeout Apache не будет использовать значение по умолчанию.

Добавьте следующие строки в ваш файл httpd.conf :

<IfModule reqtimeout_module>
  RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500
</IfModule>
Морозный Z
источник