504 Gateway Time-out

Increase PHP script execution time with Nginx

If you have a large WordPress setup or a server with limited resources, then you will often see the “504 Gateway Time-out” error.

You can follow the steps given below to increase the timeout value. PHP default is 30s.

Changes in php.ini

If you want to change max execution time limit for php scripts from 30 seconds (default) to 300 seconds.

In Apache, applications running PHP as a module above would have suffice. But in our case we need to make this change at 2 more places.

Changes in PHP-FPM

This is only needed if you have already un-commented request_terminate_timeout parameter before. It is commented by default, and takes value of max_execution_time found in php.ini

vim /etc/php5/fpm/pool.d/www.conf
request_terminate_timeout = 300

Changes in Nginx Config

To increase the time limit for example.com by

vim /etc/nginx/sites-available/example.com

If you want to increase time-limit for all-sites on your server, you can edit main nginx.conf file:

Add following in http section

Reload PHP-FPM & Nginx

Don’t forget to do this so that changes you have made will come into effect:

service php5-fpm reload service nginx reload

More

Share this:

Like this:

16 comments

Have you see this where you receive a HTTP 499 response from NginX rather than a 504? I’m having that problem with an AWS instance where I have a PHP script which terminates after 60 seconds. The script is I’ve increased the PHP execution time to 360 seconds as well as the fast_cgi_timeout but it still fails after 60 seconds. The script works from the command line though

@Steve I think you may find this helpful – http://stackoverflow.com/questions/15613452/nginx-issues-http-499-error-after-60-seconds-despite-config-php-and-aws If that doesn’t work, can you paste relevant lines from nginx error_log? There are many kind of timeouts there…

If you look into the php.ini file for “max_execution_time” you’ll see this note: Note: This directive is hardcoded to 0 for the CLI SAPI Therefore your script will never run out of time when you call it on the command line.

I am aware of CLI. This article is for CGI and FPM. This article is part of WordPress-Nginx series – https://rtcamp.com/series/wordpress-nginx-tutorials/.

Hi, We have been receiving this 504 Gateway Timeout using Nginx the last few days on our site. We have php handler DSO (as opposed to Fast CGI) running on our server. Does the above configuration tweak apply to server running DSO as php handler? Please advise.

I am having issue when I do simple form submission using post action. I am getting 504 Gateway time out error
Max_execution_time is set to 120 and we are using fast-cgi
$_POST array is blank. Can you please help me in resolving this issue

Your PHP scripts might be taking more than 120 seconds.
$_POST could be blank because of many possible reasons (considering you are debugging a POST request) Did you install Nginx & PHP by following our tutorials https://rtcamp.com/tutorials/linux/ubuntu-php-mysql-nginx-postfix/ or simply use https://rtcamp.com/easyengine/

If i setup diffrent max execution time in php-fpm ,nginx and php.ini, then which will take in execution?

As far as I know, if the execution time on nginx-sides runs out, the php script will still be running in the background, but the user will get the “504 Gateway timeout”-error. On the other side, hitting the max-execution time for php-fpm or in php itself will kill the process, write something into the PHP log file (like “PHP Fatal error: Maximum execution time of XX seconds exceeded in”…). I don’t know what the fpm would write into the log, but it (for sure) will kill the php process. Just as a hint: I had some thoughts what would happen if you are uploading files … should the time for nginx include the time the user needs to upload data? If php is running as FastCGI process (as it is here), the answer is NO.
See: http://stackoverflow.com/questions/16064282/nginx-when-is-the-fastcgi-proxy-triggered-after-request-header-or-after-reques/16187165#16187165

Error message could be different but whoever dies first will break the chain. About uploads, normal HTTP file-uploaded are buffered at nginx-level. Sending them from nginx to PHP happens quite fast if PHP and Nginx are on same machine.

Источник

Nginx, PHP-fpm и таймауты

Многих из нас интересует работа Nginx в паре с PHP-fpm и то, почему процессы прерываются а ошибок нет, я попробую рассказать об этом.

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

nginx.conf fastcgi_read_timeout Количество секунд, которое будет ждать Nginx от PHP-fpm (задаёт таймаут при чтении ответа FastCGI-сервера). Таймаут устанавливается не на всю передачу ответа, а только между двумя операциями чтения. Если по истечении этого времени FastCGI-сервер ничего не передаст, соединение закрывается. По-умолчанию 60 секунд.
php-fpm.conf request_terminate_timeout Таймаут для обслуживания одного запроса, после чего рабочий процесс будет завершен. Этот вариант следует использовать, когда опция ‘max_execution_time’ в php.ini не останавливает выполнение скрипта по каким-то причинам. Значение ‘0’ означает ‘выключено’. Доступные единицы измерения: s(econds), m(inutes), h(ours) или d(ays). Значение по умолчанию: 0, т.е. никогда.

Значит, дефолтно, если php будет отдавать ответ более 60 секунд, то nginx закроет соединение и клиент получит 504 Gateway Time-out.

Если request_terminate_timeout сработает раньше чем fastcgi_read_timeout , то nginx выдаст: 502 Bad Gateway, в противном случае: 504 Gateway Time-out

Практика

1. Укажем количество секунд, которое будет ждать Nginx от PHP-fpm:

server < . location ~ ^/app\.php(/|$) < . fastcgi_read_timeout 3; > >

2. В файл /etc/php5/fpm/php-fpm.conf добавляем таймауты нашего пула:

[site-local]

request_slowlog_timeout = 5 s
request_terminate_timeout = 30 s

3. Создаем PHP-файл /var/www/site/web/app.php с следующим содержимым:

4. Выполняем запрос к нашему сайту:

curl -i http://site.local/info.json
HTTP/1.1 504 Gateway Time-out
Server: nginx/1.9.3 (Ubuntu)
Date: Wed, 27 Apr 2016 16:58:17 GMT
Content-Type: text/html
Content-Length: 191
Connection: keep-alive




504 Gateway Time-out


nginx/1.9.3 (Ubuntu)


как видите, сработала настройка fastcgi_read_timeout.

5. Смотрим на то, что происходит в PHP-fpm:

# /usr/sbin/php5-fpm
[27-Apr-2016 16:56:35] NOTICE: fpm is running, pid 98
[27-Apr-2016 16:56:35] NOTICE: ready to handle connections
[27-Apr-2016 16:56:35] NOTICE: systemd monitor interval set to 10000ms

Обратите внимание, сработала php-fpm настройка request_slowlog_timeout :

[27-Apr-2016 16:58:16] ERROR: failed to ptrace(ATTACH) child 100: Operation not permitted (1)
[27-Apr-2016 16:58:16] WARNING: [pool site-local] child 100, script ‘/var/www/site/web/app.php’ (request: «GET /app.php») executing too slow ( 5 .385329 sec), logging

но, PHP-fpm-процесс все еще живет и выполняется (если в нем появляются ошибки, они будут записаны в логи).

Теперь внимание, сработала php-fpm настройка request_terminate_timeout :

[27-Apr-2016 16:58:44] WARNING: [pool site-local] child 100, script ‘/var/www/site/web/app.php’ (request: «GET /app.php») execution timed out ( 30 .382169 sec), terminating
[27-Apr-2016 16:58:44] WARNING: [pool site-local] child 100 exited on signal 15 (SIGTERM) after 129.988014 seconds from start

Все, после этой строки никаких ошибок Вы не увидите, т.к. PHP-fpm-процесс, обслуживающий запрос под номером 100, был убит.

Кстати: как видите лог-записи 2:

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

[27-Apr-2016 16:58:44] WARNING: [pool site-local] child 100, script ‘/var/www/site/web/app.php’ (request: «GET /app.php») execution timed out (30.382169 sec), terminating

вторая — говорит о том, каким сигналом был убит дочерний пхп-фпм процесс и сколько времени он прожил (129 секунд — за это время он мог отработать ряд запросов, но увы текущий запрос был долгим, поэтому пхп-фпм принял решение убить процесс):

[27-Apr-2016 16:58:44] WARNING: [pool site-local] child 100 exited on signal 15 (SIGTERM) after 129.988014 seconds from start

внимание: у обоих записей child 100 (это ведь один реальный процесс)

  1. В реальном проекте таймаут-параметры Nginx и PHP-fpm должны быть одинаковы (но не обязательно, главное чтобы в PHP-fpm был указан request_terminate_timeout)
  2. Собирайте статистику выполнения Nginx-запросов и если они достигают или превышают лимиты — оптимизируйте сайт или увеличивайте лимиты 🙂

Другие заметки

Ниже опишу дополнительные заметки

Неправильное ощущение

С какого-то времени PHP-fpm согласно таймауту стал завершать процессы сигналом 9:

WARNING: [pool www] child 28 exited on signal 9 (SIGKILL) after 207.053563 seconds from start

И я сразу подумал, что проблема в request_terminate_timeout , но причиной тому были настройка pm.max_requests=100

Если pm.max_requests указать больше 0, то php-fpm-master будет убивать php-fpm-kid процесс после того, как php-fpm-kid обслужил указанное кол-во http-запросов (в данном случае 100). Это конечно полезно для избежания утечек памяти при использовании сторонних библиотек. Для бесконечной обработки запросов укажите ‘0’. Эквивалент PHP_FCGI_MAX_REQUESTS. Значение по умолчанию: 0.

Зависимость php-fpm от nginx

Говорят, можно завершать php-fpm процесс, если завершился nginx-процесс который его «породил». Это было бы очень правильной стратегией, потому что нет смысла тратить ресурсы/мощности сервера, если клиент уже не собирается получать ответ.

К сожалению, у меня это сделать не получилось, но пробовал я так:

  1. устанавливал «fastcgi_ignore_client_abort on» в nginx
  2. устанавливал ignore_user_abort(false); в php-скрипте

Клиент отказался ждать

Если клиент прервал соединение с nginx (раньше чем успел ответить php-fpm), то например при двух запросах, мы увидим такие access-логи:

nginx_1 | 172.18.0.1 - - [24/Aug/2021:10:22:20 +0000] "POST /api/v2/page HTTP/1.1" 499 0 "-" "-" nginx_1 | 172.18.0.1 - - [24/Aug/2021:10:22:20 +0000] "POST /api/v2/page HTTP/1.1" 499 0 "-" "-" php-fpm_1 | 172.18.0.4 - 24/Aug/2021:10:22:19 +0000 "POST /index.php" 200 php-fpm_1 | 172.18.0.4 - 24/Aug/2021:10:22:19 +0000 "POST /index.php" 200

Почему нельзя доверять max_execution_time

PHP когда считает время выполнения скрипта (и анализируя значение выставленное функцией set_time_limit() и директивой max_execution_time) не берет в расчет время, затраченное на различные действия вне скрипта, такие как системные вызовы функции system(), sleep(), потоковые операции, запросы к базам данных и т.п..

Например, если max_execution_time равен 30 секунд, при этом стоит sleep(10), то PHP остановит выполнение скрипта только по прошествии 40 секунд.

Мало того, если тайм-аут изначально был 30 секунд, и через 25 секунд после запуска скрипта будет вызвана функция set_time_limit(20) , то скрипт будет работать максимум 45 секунд.

А еще к минусам можно отнести наличие hard_timeout которое продлевает max_execution_time на случай, если вдруг что-то застрянет (по умолчанию: 0).

Источник

How to :- Set or Increase “max_execution_time” in Nginx or php-fpm/php

Often you have seen the ” 504 Gateway Time-out ” error on your web page if you have large WordPress setup or a server with limited resources.

You can fix this issue increasing max_execution_time in Nginx or php/php-fpm php script execution time.

Set or Increase “max_execution_time” in Nginx

To increase or set max_execution_time in Nginx you will need to update your nginx vhost conf file. For example I am updating my example.com vhost file. You have to setup fastcgi_read_time as show below.

# vim /etc/nginx/sites‐available/example.com location ~ \.php$ < include /etc/nginx/fastcgi_params; fastcgi_pass unix:/var/run/php5‐fpm.sock; fastcgi_read_timeout 60; >

You can also increase time limit for all sites means for all vhost on your server, you will need to edit main nginx.conf file.

# vim /etc/nginx/nginx.conf Add following in http section http

Here I have set to 60 second. Please not down default value is 30 second by default so I have increase it to 60 seconds.

Reload Nginx

Don’t forget to do this so that changes you have made will come into effect:

# service php5‐fpm reload # service nginx reload

Set or Increase “max_execution_time” in PHP

You can change the max execution time limit for php scripts for 30 seconds (default) to 60 seconds you have to update your php.ini file like below.

# vim /etc/php5/fpm/php.ini Set.. max_execution_time = 60 

In Apache, it is sufficient to set max execution time in php.ini, but in our case we need to make this change at 2 more places.

Set or Increase “max_execution_time” in PHP-FPM

This is only needed if you have already un-commented request_terminate_timeout parameter before. It is commented by default, and takes value of max_execution_time found in php.ini file.

# vim /etc/php5/fpm/pool.d/www.conf Set.. request_terminate_timeout = 60 

That’s all, I hope this tutorial will help you.

Источник

Читайте также:  METANIT.COM
Оцените статью