PHP-FPM Ошибка: reloading in progress, sending kill signal to worker processes
Механизм плавной перезагрузки (Graceful Reload) в PHP-FPM
При выполнении команды плавной перезагрузки (systemctl reload php-fpm или отправке сигнала SIGUSR2 мастер-процессу) PHP-FPM должен обновить конфигурацию без потери активных пользовательских соединений. Мастер-процесс перечитывает конфигурационные файлы, открывает новые сокеты, запускает новое поколение воркеров и отправляет сигнал SIGQUIT (Graceful Stop) старым рабочим процессам, ожидая, пока они штатно завершат текущие HTTP-запросы. Если старый воркер зависает на выполнении медленного скрипта, долгом запросе к базе данных или внешнем сокете, мастер по истечении лимита process_control_timeout принудительно убивает его жестким сигналом SIGKILL:
«NOTICE: reload: reloading in progress, sending kill signal to worker processes»
«WARNING: [pool www] child 24510 exited on signal 9 (SIGKILL) after 10.000214 seconds from start»
Бизнес-риски
Обрыв активных пользовательских операций во время планового деплоя релизов (CI/CD Zero-Downtime Deployment нарушается), кратковременные всплески ошибок 502 Bad Gateway в Nginx.
Сравнение стратегий перезапуска службы PHP-FPM
| Команда перезапуска | Сигнал ядра | Влияние на активные запросы |
|---|---|---|
systemctl reload php-fpm | SIGUSR2 (Graceful) | Воркеры завершают текущие запросы до истечения process_control_timeout. |
systemctl restart php-fpm | SIGTERM (Immediate) | Все воркеры мгновенно убиваются, все активные запросы обрываются (502 Error). |
Регламент настройки корректного Graceful Reload без обрыва запросов
Шаг 1: Настройка process_control_timeout в глобальной конфигурации
По умолчанию параметр process_control_timeout установлен в 0 (отключен), что заставляет мастер убивать воркеры мгновенно, не давая времени на завершение запросов:
# 1. Откройте главный конфигурационный файл php-fpm.conf:
sudo nano /etc/php/8.2/fpm/php-fpm.conf
# 2. В секции [global] установите таймаут ожидания дочерних процессов (например, 15-30 секунд):
[global]
process_control_timeout = 20s
# 3. Перезапустите службу для применения глобального параметра:
sudo systemctl restart php8.2-fpmШаг 2: Обеспечение плавного деплоя в скриптах CI/CD
При выкатке новых версий кода используйте корректную последовательность сигналов:
# В скрипте деплоя:
# 1. Проверка синтаксиса конфигурации:
php-fpm8.2 -t || exit 1
# 2. Мягкая перезагрузка через отправку сигнала SIGUSR2 главному мастер-процессу:
sudo kill -USR2 $(cat /run/php/php8.2-fpm.pid)
# 3. Ожидание плавного переключения воркеров (2-3 секунды):
sleep 3Шаг 3: Локализация воркеров, препятствующих плавному завершению
# Просмотр процессов, зависших в состоянии завершения:
ps aux | grep -E "php-fpm: pool" | grep -v grep
# Анализ медленных скриптов, удерживающих воркеры, в slowlog:
sudo tail -n 50 /var/log/php8.2-fpm.slow.logТиповые ошибки администраторов
- Использование systemctl restart вместо reload при обновлении кода:
restartполностью гасит мастер-процесс и сокет, гарантируя появление ошибок 502 у всех пользователей, находившихся на сайте в эту секунду. - Установка process_control_timeout = 0: Превращает любую попытку graceful reload в мгновенное жесткое убийство процессов.
Эксперты ITSTM выстроят архитектуру бесшовного развертывания (Zero-Downtime Deployment) и настроят корректную обработку сигналов процессов.
Частые вопросы (FAQ)
Почему при reload мастер-процесс меняет свой PID?
При отправке сигнала USR2 мастер-процесс FPM выполняет exec() самого себя, порождая новый управляющий мастер с новым PID, при этом старый сокет прослушивания передается новому процессу без закрытия.
Что происходит с клиентским запросом, если воркер убит по process_control_timeout?
Соединение FastCGI аварийно закрывается, воркер уничтожается сигналом SIGKILL, а веб-сервер Nginx регистрирует 'recv() failed (104: Connection reset by peer)' и отдает пользователю 502 ошибку.
Помогает ли OPcache при выполнении reload?
Да, если используется opcache.validate_timestamps=0 для максимальной производительности, именно graceful reload корректно сбрасывает кэш байткода в разделяемой памяти без простоя сайта.
Как узнать PID мастер-процесса PHP-FPM?
Посмотрите содержимое PID-файла: cat /run/php/php-fpm.pid или выполните systemctl show --property MainPID php8.2-fpm.