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, о которых сообщалось в других записях.

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

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

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

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

Http://pastebin.com/WQX4AqEU

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

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

Сохраните это в веб-корне, а затем протестируйте. Если вы запустите скрипт из командной строки с использованием php или php-cgi, он будет работать. Если вы получите доступ к сценарию через веб-страницу и зайдете в журнал доступа /var/log/nginx/example.access.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, чтобы увеличить время ожидания с этой стороны

Сначала я редактирую файл /etc/nginx/nginx.conf и добавляю это в директиву http fastcgi_read_timeout 300;

Далее я редактирую файл /etc/nginx/с поддержкой сайтов/пример , который мы создали ранее (см. Запись 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$ каталога сервера

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() с веб-доступной страницы. Я просто не понимаю, я на самом деле думаю, что слишком много было увеличено, так как для этого просто нужно max_execution_time PHP, default_socket_timeout изменен, а также NGINX в fastcgi_read_timeout в просто директива server->местоположение.

Обновление 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 вкл.; изменяет ответ с HTTP 499 на HTTP 200, хотя конечному клиенту по-прежнему ничего не возвращается.

Обновление 3

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

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

Author: Community, 2013-03-25

5 answers

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

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

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

 58
Author: TFAtTheMoon, 2015-11-06 18:54:51

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

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

 1
Author: Waheed, 2017-04-16 07:21:50

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

У нас здесь 3 элемента: nginx, php-fpm, php. Как вы сказали, те же настройки php под apache в порядке. Неужели это та же самая, не та же самая установка? Вы пробовали apache вместо nginx на той же ОС/хосте/и т.д.?

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

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

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

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

  • запрос php-fpm_terminate_timeout
  • fastcgi_ignore_client_аборт nginx
 0
Author: gaRex, 2013-03-25 14:18:58

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

 0
Author: Rajeev kumar, 2016-10-18 12:48:28

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

 0
Author: Souvik Ray, 2018-04-04 07:24:11