Nginx 504: FastCGI PHP execution timed out — Решение проблемы
При выполнении длительных PHP-скриптов сервер возвращает код ответа 504 Gateway Time-out. В логе Nginx регистрируется аварийное прерывание скрипта: FastCGI sent in stderr: "PHP message: PHP Fatal error: Maximum execution time of 30 seconds exceeded" или request_terminate_timeout exceeded.
| Уровень конфигурации | Параметр | Значение по умолчанию |
|---|---|---|
php.ini | max_execution_time | 30 секунд |
php-fpm pool (www.conf) | request_terminate_timeout | 0 (или 30s-60s) |
nginx.conf | fastcgi_read_timeout | 60 секунд |
- Скрипт аварийно прерывается интерпретатором PHP точно по достижении лимита времени.
- В журнале
php-fpm.logфиксируется принудительное уничтожение процесса:[WARNING] [pool www] child ... exited on signal 15 (SIGTERM) after ... seconds.
- Увеличьте максимальное время выполнения скрипта в
/etc/php/8.x/fpm/php.ini:max_execution_time = 300 max_input_time = 300 memory_limit = 512M - Проверьте и скорректируйте жесткий таймаут пула PHP-FPM в
/etc/php/8.x/fpm/pool.d/www.conf:; Выставите 300s или 0 (отключено): request_terminate_timeout = 300s - Увеличьте время ожидания со стороны Nginx в конфигурации сайта:
location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php8.2-fpm.sock; fastcgi_read_timeout 300s; fastcgi_send_timeout 300s; } - Перезапустите PHP-FPM и Nginx:
sudo systemctl restart php8.2-fpm sudo systemctl reload nginx - Включите медленный лог PHP-FPM для локализации узких мест в коде:
# В www.conf: slowlog = /var/log/php-fpm/www-slow.log request_slowlog_timeout = 5s
request_terminate_timeout в PHP-FPM имеет приоритет над max_execution_time из php.ini, так как он принудительно убивает воркер через системный вызов ядра, игнорируя блокировки в PHP функциях sleep() или curl_exec().Частые вопросы (FAQ)
Почему max_execution_time=0 не помогает при зависании cURL?
В Linux системные вызовы потоков ввода-вывода (например, зависший file_get_contents или сетевой cURL) не учитываются счетчиком времени выполнения CPU скрипта. Помогает только request_terminate_timeout в pool.d/www.conf.
Как включить логирование долгих запросов в PHP-FPM?
Задайте директивы request_slowlog_timeout = 5s и slowlog = /var/log/php.slow.log в конфигурации пула www.conf.
Чем опасен слишком большой max_execution_time?
При наплыве медленных запросов все воркеры PHP-FPM (pm.max_children) окажутся заняты и перестанут отвечать новым клиентам, что приведет к полному отказу веб-ресурса.
Как увеличить таймаут для одного конкретного PHP-файла?
В начале целевого PHP-скрипта добавьте строку: set_time_limit(300); или ini_set('max_execution_time', '300');.