NginX выдает ошибку HTTP 499 через 60 секунд, несмотря на конфигурацию. (PHP и AWS)

в конце прошлой недели я заметил проблему на одном из моих средних экземпляров AWS, где Nginx всегда возвращает ответ HTTP 499, если запрос занимает более 60 секунд. Страница запрашивается-это PHP-скрипт

Я потратил несколько дней, пытаясь найти ответы и попробовал все, что я могу найти в интернете, включая несколько записей здесь о переполнении стека, ничего не работает.

Я попытался изменить настройки PHP, настройки PHP-FPM и Nginx настройки. Вы можете увидеть вопрос, который я поднял на форумах NginX в пятницу (http://forum.nginx.org/read.php?9,237692) хотя это не получило ответа, поэтому я надеюсь, что смогу найти ответ здесь, прежде чем я буду вынужден вернуться к Apache, который, как я знаю, просто работает.

этой не та же проблема, что и ошибки HTTP 500, сообщенные в других записях.

я смог воспроизвести проблему со свежим микро AWS экземпляр NginX с использованием PHP 5.4.11.

чтобы помочь всем, кто хочет увидеть проблему в действии, я собираюсь провести вас через настройку, которую я запустил для последнего тестового сервера Micro.

вам нужно запустить новый экземпляр AWS Micro (так что это бесплатно) с помощью AMI ami-c1aaabb5

эта запись PasteBin имеет полную настройку для запуска, чтобы отразить мою тестовую среду. Вам просто нужно изменить example.com в конфигурации NginX на конец

http://pastebin.com/WQX4AqEU

как только это настроено, вам просто нужно создать образец PHP-файла, который я тестирую с помощью которого

<?php
sleep(70);
die( 'Hello World' );
?>

сохраните это в webroot, а затем проверьте. Если вы запустите скрипт из командной строки с помощью PHP или php-cgi, то он будет работать. Если вы получаете доступ к скрипту через веб-страницу и хвост журнала доступа /var/log/nginx / пример.доступ.log, вы заметите, что вы получаете HTTP 1.1 499 ответ через 60 секунд.

теперь, когда вы можете увидеть тайм-аут, я пройду через некоторые изменения конфигурации, которые я сделал для PHP и NginX, чтобы попытаться обойти это. Для PHP я создам несколько конфигурационных файлов, чтобы их можно было легко отключить

обновите конфигурацию PHP FPM, чтобы включить внешние файлы конфигурации

sudo echo '
include=/usr/local/php/php-fpm.d/*.conf
' >> /usr/local/php/etc/php-fpm.conf

создайте новую конфигурацию PHP-FPM для переопределения запроса ожидания

sudo echo '[www]
request_terminate_timeout = 120s
request_slowlog_timeout = 60s
slowlog = /var/log/php-fpm-slow.log ' >
/usr/local/php/php-fpm.d/timeouts.conf

измените некоторые глобальные настройки, чтобы гарантировать, что интервал аварийного перезапуска составляет 2 минуты

# Create a global tweaks
sudo echo '[global]
error_log = /var/log/php-fpm.log
emergency_restart_threshold = 10
emergency_restart_interval = 2m
process_control_timeout = 10s
' > /usr/local/php/php-fpm.d/global-tweaks.conf

Далее мы изменим некоторые PHP.Настройки INI, снова используя отдельные файлы

# Log PHP Errors
sudo echo '[PHP]
log_errors = on
error_log = /var/log/php.log
' > /usr/local/php/conf.d/errors.ini

sudo echo '[PHP]
post_max_size=32M
upload_max_filesize=32M
max_execution_time = 360
default_socket_timeout = 360
mysql.connect_timeout = 360
max_input_time = 360
' > /usr/local/php/conf.d/filesize.ini

как вы можете видеть, это увеличивает тайм-аут сокета до 3 минут и поможет регистрировать ошибки.

наконец, я отредактирую некоторые настройки NginX, чтобы увеличить тайм-аут этой стороны

первый Я редактирую файл /и т. д./nginx/nginx в.conf и добавьте это в директиву http fastcgi_read_timeout 300;

далее я редактирую файл / etc/nginx/sites-включено / пример который мы создали ранее (см. Запись pastebin) и добавьте следующие настройки в сервер директива

client_max_body_size    200;
client_header_timeout   360;
client_body_timeout     360;
fastcgi_read_timeout    360;
keepalive_timeout       360;
proxy_ignore_client_abort on;
send_timeout            360;
lingering_timeout       360;

наконец, я добавляю следующее в расположение ~ .в PHP$ раздел сервера dir

fastcgi_read_timeout 360;
fastcgi_send_timeout 360;
fastcgi_connect_timeout 1200;

перед повторите попытку сценария, запустите nginx и php-fpm, чтобы убедиться, что новые настройки были подобраны. Затем я пытаюсь получить доступ к странице и по-прежнему получать запись HTTP/1.1 499 в Примере NginX.ошибка.бревно.

Итак, где я ошибаюсь? Это просто работает на apache, когда я устанавливаю максимальное время выполнения PHP до 2 минут.

Я вижу, что настройки PHP были подобраны под управлением phpinfo () из веб-страницы. Я просто не понимаю, я на самом деле подумайте, что слишком много было увеличено, так как ему просто нужно PHP max_execution_time, default_socket_timeout изменен, а также NginX в fastcgi_read_timeout только в директиве server->location.

обновление 1

выполнив еще один тест, чтобы показать, что проблема не в том, что клиент умирает, я изменил тестовый файл на

<?php
file_put_contents('/www/log.log', 'My first data');
sleep(70);
file_put_contents('/www/log.log','The sleep has passed');
die('Hello World after sleep');
?>

если я запускаю скрипт с веб-страницы, то Я вижу, что содержимое файла будет установлено в первую строку. Через 60 секунд в журнале NginX появится ошибка. Через 10 секунд содержимое файла изменяется на 2-ю строку, доказывая, что PHP завершает процесс.

обновление 2

задание fastcgi_ignore_client_abort on; изменяет ответ с HTTP 499 на HTTP 200, хотя ничто не возвращается конечному клиенту.

обновление 3

имея установленный Apache и PHP (5.3.10) на поле прямо (с использованием apt), а затем увеличение времени выполнения проблема, похоже, также происходит на Apache. Симптомы такие же, как NginX сейчас, ответ HTTP200, но фактическое время подключения клиента перед рукой.

Я также начал замечать в журналах NginX, что если я тестирую Firefox, он делает двойной запрос (например,PHP-скрипт выполняется дважды, когда более 60 секунд). Хотя это, похоже, клиент, запрашивающий при сбое скрипта

5 ответов


причиной проблемы являются упругие балансировщики нагрузки на AWS. Они, по умолчанию, тайм-аут после 60 секунд бездействия, что и было причиной проблемы.

Так что это был не NginX, PHP-FPM или PHP, а балансировщик нагрузки.

чтобы исправить это, просто перейдите на вкладку "описание" ELB, прокрутите вниз и нажмите ссылку" (Edit) "рядом со значением, которое говорит"Время простоя: 60 секунд"


Я думал, что оставлю свои два цента. Во-первых, проблема не связана с php(все еще может быть связана с php, php всегда удивляет меня :P ). Это точно. его в основном вызвано прокси-сервером, более конкретно, именем хоста / псевдонимами, в вашем случае это может быть балансировщик нагрузки запрашивает nginx, а nginx вызывает балансировщик нагрузки, и он продолжает идти таким образом.

Я испытал как проблема с nginx в качестве нагрузки балансировщик и Apache в качестве веб-сервера/прокси-сервера


вам нужно найти, в каком месте проблемы живут. Я не знаю точного ответа, но давайте попробуем найти его.

мы имеем здесь 3 элемента: nginx, php-fpm, php. Как вы сказали, те же настройки php под apache в порядке. Это же не та же самая настройка? Вы пробовали apache вместо nginx на той же OS/host/etc.?

Если мы увидим, что php не подозревается, то у нас есть два подозреваемых: nginx & php-fpm.

чтобы исключить nginx: попробуйте настроить ту же" систему " на ruby. Видеть https://github.com/garex/puppet-module-nginx чтобы получить идею установить простейшую установку ruby. Или используйте google (может быть, это будет еще лучше).

мой главный подозреваемый здесь-php-fpm.

попробуйте сыграть с этими настройками:

  • php-fpm request_terminate_timeout
  • nginx по fastcgi_ignore_client_abort

на самом деле я столкнулся с той же проблемой на одном сервере, и я понял, что после изменений конфигурации nginx я не перезапускал сервер nginx, поэтому с каждым ударом url nginx я получал 499 http-ответ. После перезагрузки nginx он начал работать правильно с ответами http 200.


не уверен, что кто-то еще столкнулся с этим, но для меня это произошло после того, как я поставил / в конце url моего экземпляра.Это дало 499 ошибки и только после того, как я убрал /, Он дал мне 200 и все прошло хорошо.