Как перезапустить PHP-FPM: все методы с объяснениями для Linux-администраторов
PHP-FPM (PHP FastCGI Process Manager) — это высокопроизводительный менеджер процессов, который обрабатывает выполнение PHP как отдельный сервис, независимый от веб-сервера. Перезапуск PHP-FPM применяет изменения конфигурации из `php.ini` или `php-fpm.conf`, освобождает утечки памяти в долго работающих пулах воркеров и восстанавливает работу после зависших дочерних процессов — всё это без затрагивания Nginx, Apache или любого другого компонента вашего стека.
Это руководство охватывает все практические методы перезапуска, доступные в современных и устаревших дистрибутивах Linux, включая управление на основе сигналов, среды с несколькими версиями и стратегии плавной перезагрузки для развёртывания в продакшене без простоев.
Зачем нужен перезапуск PHP-FPM
Понимание точной причины перезапуска предотвращает ненужные простои и помогает выбрать наименее разрушительный метод:
- Изменения конфигурации: Изменения в `php.ini`, `php-fpm.conf` или любом файле конфигурации пула в `/etc/php/<version>/fpm/pool.d/` требуют перезапуска или перезагрузки для вступления в силу. PHP-FPM читает эти файлы только при запуске или по сигналу `USR2`.
- Освобождение памяти: Рабочие процессы PHP-FPM накапливают память со временем, особенно на высоконагруженных серверах, запускающих ресурсоёмкие приложения. Контролируемый перезапуск перезапускает воркеры и сбрасывает их потребление памяти.
- Зависшие воркеры: Если дочерние процессы переходят в состояние зомби или перестают принимать соединения, перезапуск очищает таблицу процессов и создаёт новый пул.
- Ротация логов: После того как `logrotate` переименовывает или сжимает активный файл лога, PHP-FPM всё ещё удерживает файловый дескриптор старого inode. Перезагрузка заставляет его открыть новый файловый дескриптор, обеспечивая непрерывность логирования.
- Инвалидация OPcache: При развёртывании нового кода приложения перезапуск PHP-FPM полностью сбрасывает OPcache, гарантируя, что воркеры выполняют обновлённый байткод, а не устаревшие кешированные версии.
- Изменения расширений или модулей: Добавление или удаление PHP-расширений в `php.ini` требует полного перезапуска — одной перезагрузки недостаточно, поскольку список расширений оценивается при инициализации процесса.
Предварительные требования
Перед выполнением любой команды перезапуска убедитесь в следующем:
- У вас есть доступ `root` или привилегии `sudo` на сервере.
- Вы знаете точное имя службы PHP-FPM в вашей системе (оно варьируется в зависимости от дистрибутива и установленной версии).
- Вы определили путь к PID-файлу, если планируете использовать управление на основе сигналов (обычно `/run/php/php<version>-fpm.pid` в Debian/Ubuntu или `/run/php-fpm/php-fpm.pid` в RHEL/CentOS).
Чтобы узнать активное имя службы PHP-FPM:
“`bash
systemctl list-units –type=service | grep fpm
“`
Чтобы найти путь к PID-файлу:
“`bash
grep -i pid /etc/php/*/fpm/php-fpm.conf
“`
Метод 1: Перезапуск PHP-FPM с помощью systemctl (рекомендуется)
`systemctl` — это авторитетный менеджер служб во всех дистрибутивах на основе systemd, включая Ubuntu 16.04+, Debian 8+, CentOS 7+, AlmaLinux, Rocky Linux и Fedora. Это правильный инструмент для подавляющего большинства продакшен-серверов.
Стандартный перезапуск
“`bash
sudo systemctl restart php8.2-fpm
“`
Замените `php8.2-fpm` на версию, установленную в вашей системе (например, `php7.4-fpm`, `php8.1-fpm`, `php-fpm`). В системах на основе RHEL служба обычно называется `php-fpm` без префикса версии.
Перезагрузка без полного перезапуска
Перезагрузка отправляет сигнал `USR2` внутренне, инструктируя мастер-процесс перечитать конфигурацию и плавно заменить рабочие процессы. Текущие выполняемые запросы завершаются перед перезапуском воркеров:
“`bash
sudo systemctl reload php8.2-fpm
“`
Ключевое различие: `reload` не вызывает простоев и предпочтителен для изменений конфигурации в продакшене. `restart` немедленно завершает все воркеры, что может прервать активные соединения при высокой нагрузке.
Остановка и запуск по отдельности
“`bash
sudo systemctl stop php8.2-fpm
sudo systemctl start php8.2-fpm
“`
Используйте этот двухэтапный подход, когда нужно убедиться, что служба полностью остановлена перед повторным запуском — например, после изменения пути сокета `listen` или значительного изменения `pm.max_children`.
Проверка состояния службы
“`bash
sudo systemctl status php8.2-fpm
“`
Корректный вывод показывает `Active: active (running)` и отображает PID мастер-процесса. Если служба не запустилась, `systemctl status` отображает последние записи журнала, что быстрее, чем ручной поиск по файлам логов.
Для потоковой трансляции логов во время перезапуска:
“`bash
sudo journalctl -u php8.2-fpm -f
“`
Метод 2: Перезапуск PHP-FPM с помощью устаревшей команды service
Команда `service` является оберткой совместимости вокруг `systemctl` в современных системах и напрямую вызывает скрипты SysVinit в старых дистрибутивах (Ubuntu 14.04, CentOS 6, Debian 7). Она остаётся актуальной при управлении серверами, которые не были перенесены на systemd.
“`bash
sudo service php-fpm restart
“`
Для независимой остановки и запуска:
“`bash
sudo service php-fpm stop
sudo service php-fpm start
“`
В дистрибутивах, всё ещё использующих SysVinit, базовый скрипт находится по адресу `/etc/init.d/php-fpm`. Вы можете вызвать его напрямую, если обёртка `service` недоступна:
“`bash
sudo /etc/init.d/php-fpm restart
“`
Метод 3: Управление несколькими версиями PHP одновременно
Серверы с панелями управления, такими как cPanel, Plesk, или пользовательскими мультитенантными конфигурациями, часто имеют несколько версий PHP, установленных параллельно. Каждая версия работает как независимая служба PHP-FPM со своим деревом конфигурации, сокетом и PID-файлом.
Перезапуск конкретной версии
“`bash
Debian/Ubuntu (packages from ondrej/php PPA or distribution repos)
sudo systemctl restart php7.4-fpm
sudo systemctl restart php8.1-fpm
sudo systemctl restart php8.2-fpm
RHEL/CentOS with Remi repository
sudo systemctl restart php74-php-fpm
sudo systemctl restart php81-php-fpm
“`
Перезапуск всех версий PHP-FPM одновременно
Когда общесистемное изменение затрагивает все версии (например, обновление общей библиотеки), перезапустите все экземпляры одним циклом:
“`bash
for ver in 7.4 8.1 8.2; do
sudo systemctl restart php${ver}-fpm && echo "php${ver}-fpm restarted"
done
“`
Определение версии, обслуживающей конкретный сайт
Каждый виртуальный хост Nginx или VirtualHost Apache сопоставлен с конкретным сокетом PHP-FPM. Проверьте конфигурацию сайта, чтобы определить, какая версия активна, перед перезапуском:
“`bash
Nginx
grep fastcgi_pass /etc/nginx/sites-enabled/yourdomain.conf
Apache with mod_proxy_fcgi
grep SetHandler /etc/apache2/sites-enabled/yourdomain.conf
“`
Если вы управляете сервером через панель управления, VPS с cPanel предоставляет графический интерфейс для переключения версий PHP для каждого домена без ручного перезапуска служб.
Метод 4: Отправка POSIX-сигналов напрямую мастер-процессу
Мастер-процесс PHP-FPM реагирует на определённый набор POSIX-сигналов. Этот метод полностью обходит систему инициализации и даёт вам точный низкоуровневый контроль — необходимый в контейнеризированных средах, пользовательских системах инициализации или когда `systemctl` недоступен.
Таблица справочника сигналов
| Сигнал | Эффект | Сценарий использования |
|---|---|---|
| — | — | — |
| `SIGTERM` (15) | Плавное завершение | Упорядоченная остановка, ожидание завершения воркеров |
| `SIGINT` (2) | Немедленное завершение | Принудительная остановка при зависании плавного завершения |
| `SIGQUIT` (3) | Плавная остановка | Эквивалент SIGTERM для PHP-FPM |
| `SIGUSR1` (10) | Повторное открытие файлов логов | Обновление файлового дескриптора лога после logrotate |
| `SIGUSR2` (12) | Плавная перезагрузка | Перезагрузка конфигурации, перезапуск воркеров без разрыва соединений |
| `SIGKILL` (9) | Принудительное завершение | Крайняя мера — без очистки, без плавной обработки |
Перезагрузка конфигурации (без простоев)
“`bash
sudo kill -USR2 $(cat /run/php/php8.2-fpm.pid)
“`
Это функционально эквивалентно `systemctl reload` и является наиболее безопасным способом применения изменений `php-fpm.conf` или конфигурации пула на работающем сервере.
Повторное открытие файлов логов после ротации
“`bash
sudo kill -USR1 $(cat /run/php/php8.2-fpm.pid)
“`
Выполните это сразу после того, как `logrotate` завершит работу, чтобы предотвратить продолжение записи PHP-FPM в переименованный файл лога.
Плавное завершение
“`bash
sudo kill -QUIT $(cat /run/php/php8.2-fpm.pid)
“`
Мастер-процесс прекращает принимать новые соединения и ожидает завершения всех активных воркерами текущих запросов перед выходом. После этого выполните `sudo systemctl start php8.2-fpm` для повторного запуска службы.
Важно: Всегда проверяйте путь к PID-файлу перед использованием этих команд. Неверный путь приведёт к отправке сигнала несвязанному процессу. Проверьте с помощью:
“`bash
cat /run/php/php8.2-fpm.pid
ps aux | grep php-fpm
“`
Метод 5: Принудительное завершение процессов PHP-FPM с помощью pkill или killall
Это крайняя мера для ситуаций, когда PHP-FPM полностью перестал отвечать и ни `systemctl`, ни управление на основе сигналов не дают результата. Она безусловно завершает все процессы PHP-FPM, что прервёт все выполняемые запросы.
“`bash
sudo pkill -9 php-fpm
“`
Или с использованием `killall`:
“`bash
sudo killall -9 php-fpm
“`
После принудительного завершения служба не перезапустится автоматически, если только она не управляется супервизором процессов. Запустите её явно:
“`bash
sudo systemctl start php8.2-fpm
“`
Когда использовать: Накопление зомби-процессов, неуправляемые дочерние процессы, потребляющие 100% CPU, или ситуации, когда мастер-процесс жив, но больше не управляет своим пулом. Прежде чем прибегать к `pkill -9`, попробуйте `kill -QUIT` на PID мастер-процесса — это значительно менее разрушительно.
Метод 6: Перезапуск веб-сервера для косвенного воздействия на PHP-FPM
Перезапуск Nginx или Apache не перезапускает PHP-FPM. Поскольку PHP-FPM работает как полностью независимая служба, взаимодействующая через Unix-сокет или TCP-порт, перезапуск веб-сервера затрагивает только HTTP-уровень. Это распространённое заблуждение.
“`bash
Nginx
sudo systemctl restart nginx
Apache
sudo systemctl restart apache2
“`
Единственный сценарий, когда перезапуск веб-сервера имеет отношение к PHP-FPM, — это когда вы изменили директиву `fastcgi_pass` в Nginx или правило `ProxyPassMatch` в Apache, чтобы указать на другой сокет PHP-FPM. В этом случае Nginx должен перезагрузить свою конфигурацию для подключения к новому пути сокета — но сам PHP-FPM всё равно требует отдельного перезапуска.
При полном техническом обслуживании стека перезапускайте обе службы в правильном порядке: сначала PHP-FPM, затем веб-сервер.
Сравнение: методы перезапуска PHP-FPM в обзоре
| Метод | Пример команды | Уровень нарушения работы | Сценарий использования |
|---|---|---|---|
| — | — | — | — |
| `systemctl restart` | `systemctl restart php8.2-fpm` | Средний — разрывает активные соединения | Стандартные изменения конфигурации, dev/staging |
| `systemctl reload` | `systemctl reload php8.2-fpm` | Отсутствует — плавный перезапуск воркеров | Изменения конфигурации в продакшене |
| `kill -USR2` | `kill -USR2 $(cat /run/php/php-fpm.pid)` | Отсутствует — плавная перезагрузка | Продакшен, контейнеризированные среды |
| `kill -QUIT` | `kill -QUIT $(cat /run/php/php-fpm.pid)` | Низкий — ожидает завершения запросов | Контролируемое завершение перед обслуживанием |
| `kill -USR1` | `kill -USR1 $(cat /run/php/php-fpm.pid)` | Отсутствует — только обновление файлового дескриптора лога | После logrotate |
| `service restart` | `service php-fpm restart` | Средний | Устаревшие системы SysVinit |
| `pkill -9` | `pkill -9 php-fpm` | Высокий — немедленное завершение | Неотвечающие процессы, крайняя мера |
| Перезапуск веб-сервера | `systemctl restart nginx` | Только веб-уровень | Обновление пути сокета fastcgi в конфигурации веб-сервера |
Конфигурация пула PHP-FPM: что требует перезапуска, а что — перезагрузки
Не все изменения конфигурации имеют одинаковый вес. Знание того, какие изменения требуют полного перезапуска, а какие — простой перезагрузки, снижает ненужные простои:
Перезагрузки (`USR2` / `systemctl reload`) достаточно для:
- `pm.max_children`, `pm.start_servers`, `pm.min_spare_servers`, `pm.max_spare_servers`
- `request_terminate_timeout`, `request_slowlog_timeout`
- Изменений пути `slowlog`
- Директив `php_admin_value` и `php_flag` в файлах пула
- Изменений пути `access.log`
Требуется полный перезапуск для:
- Изменений директивы `listen` (путь сокета или TCP-порт)
- Добавления или удаления PHP-расширений в `php.ini`
- Изменения директив `user` или `group` в пуле
- Изменения путей `include` в `php-fpm.conf`
- Обновления самого бинарного файла PHP (обновления версии)
Лучшие практики перезапуска PHP-FPM в продакшене
- Всегда предпочитайте `reload` вместо `restart` на работающих серверах. Перезагрузка плавно перезапускает воркеры, завершая выполняемые запросы перед созданием замен. Жёсткий перезапуск немедленно разрывает все активные соединения.
- Проверяйте конфигурацию перед перезагрузкой. PHP-FPM предоставляет встроенную проверку синтаксиса, которая предотвращает загрузку неверной конфигурации:
“`bash
sudo php-fpm8.2 -t
Expected output: NOTICE: configuration file … test is successful
“`
- Проверяйте логи до и после. Просматривайте `/var/log/php8.2-fpm.log` (или путь, определённый в вашем `php-fpm.conf`) на наличие записей `WARNING` или `ERROR`, указывающих на сбои запуска пула.
- Отслеживайте метрики пула воркеров после перезапуска. Используйте страницу статуса PHP-FPM (включается через `pm.status_path` в конфигурации пула), чтобы убедиться, что ожидаемое количество воркеров активно и простаивает после перезапуска.
- Автоматизируйте с помощью конвейеров развёртывания. В рабочих процессах CI/CD запускайте `systemctl reload php-fpm` как хук после развёртывания, а не полный перезапуск. Это обеспечивает развёртывание без простоев при каждом коммите кода.
- Настройте `pm.max_requests` для автоматического перезапуска воркеров. Вместо планирования периодических перезапусков для борьбы с утечками памяти настройте `pm.max_requests = 500` (или подходящее значение), чтобы автоматически перезапускать каждый воркер после обработки фиксированного количества запросов.
PHP-FPM на VPS и выделенных серверах
Используемый метод перезапуска также зависит от вашей хостинговой среды. На тарифе VPS Хостинг с полным root-доступом все методы, описанные в этом руководстве, доступны без ограничений. У вас есть прямой доступ к `systemctl`, PID-файлу и таблице процессов.
На Выделенных серверах, где вы контролируете весь аппаратный стек, вы можете дополнительно настроить PHP-FPM с `pm = ondemand` или `pm = dynamic` для точной настройки поведения создания воркеров, а также использовать drop-in файлы `systemd` для настройки политик перезапуска (например, `Restart=on-failure`, `RestartSec=5s`).
Если вы управляете несколькими клиентскими сайтами через решение Панели управления VPS, операции перезапуска PHP-FPM часто абстрагированы в пользовательском интерфейсе панели, но понимание базовых команд остаётся необходимым для устранения неполадок в ситуациях, когда сама панель не отвечает.
Для приложений, требующих высокой конкурентности PHP — таких как Laravel, WordPress multisite или магазины WooCommerce — сочетание PHP-FPM с правильно настроенной конфигурацией пула на Выделенном сервере устраняет конкуренцию за ресурсы, которую вносят общие среды.
Матрица технических решений: выбор правильного метода перезапуска
Используйте эту матрицу для выбора правильного подхода в зависимости от вашей конкретной ситуации:
| Ситуация | Рекомендуемый метод |
|---|---|
| — | — |
| Применены изменения к `php.ini` или файлам пула `.conf` | `systemctl reload php<ver>-fpm` |
| Добавлено новое PHP-расширение | `systemctl restart php<ver>-fpm` |
| PHP-FPM не отвечает, мастер-процесс жив | `kill -QUIT <master_pid>`, затем `systemctl start` |
| PHP-FPM полностью завис, нет реакции на сигналы | `pkill -9 php-fpm`, затем `systemctl start` |
| Обновление файлового дескриптора лога после logrotate | `kill -USR1 <master_pid>` |
| Развёртывание нового кода приложения (сброс OPcache) | `systemctl reload php<ver>-fpm` или `kill -USR2` |
| Изменён путь сокета `listen` | `systemctl restart php<ver>-fpm` |
| Несколько версий PHP, одну нужно обновить | Только `systemctl restart php<specific-ver>-fpm` |
| Контейнеризированная среда без systemd | `kill -USR2 <master_pid>` через скрипт точки входа |
| Проверка синтаксиса конфигурации перед применением | Сначала `php-fpm<ver> -t`, затем перезагрузка/перезапуск |
FAQ
В чём разница между `systemctl restart` и `systemctl reload` для PHP-FPM?
`restart` немедленно завершает все мастер- и рабочие процессы и запускает их заново, прерывая все выполняемые запросы. `reload` отправляет сигнал `USR2` мастер-процессу, который создаёт новые воркеры с обновлённой конфигурацией, пока существующие воркеры завершают свои текущие запросы перед выходом. Всегда используйте `reload` в продакшене.
Как найти правильное имя службы PHP-FPM на моём сервере?
Выполните `systemctl list-units –type=service | grep fpm`. В системах Debian/Ubuntu с несколькими версиями из PPA `ondrej/php` вы увидите записи вида `php7.4-fpm.service` и `php8.2-fpm.service`. В RHEL/CentOS с репозиторием Remi соглашение об именовании — `php74-php-fpm.service`.
Влияет ли перезапуск PHP-FPM на активные соединения с базой данных или пользовательские сессии?
Жёсткий перезапуск (`systemctl restart`) немедленно завершает все рабочие процессы, закрывая все постоянные соединения с базой данных, удерживаемые этими воркерами. Пользовательские сессии, хранящиеся в файлах или базе данных, не затрагиваются, поскольку они существуют независимо от воркеров PHP-FPM. Плавная перезагрузка (`systemctl reload`) позволяет воркерам завершить текущие запросы, поэтому постоянные соединения закрываются корректно.
Почему PHP-FPM не запускается после перезапуска?
Наиболее распространённые причины: синтаксическая ошибка в `php.ini` или файле конфигурации пула, конфликт порта или пути сокета (другой процесс уже прослушивает настроенный адрес `listen`), или недостаточные права доступа к директории сокета. Выполните `php-fpm<ver> -t` для проверки синтаксиса конфигурации и проверьте `journalctl -u php<ver>-fpm` для получения точного сообщения об ошибке.
Можно ли перезапустить PHP-FPM без root или sudo привилегий?
Нет, при стандартной установке Linux. Мастер-процесс PHP-FPM работает от имени root (он сбрасывает привилегии до настроенных `user`/`group` для рабочих процессов), а управление системными службами требует повышенных привилегий. В средах общего хостинга хостинг-провайдер обрабатывает перезапуски PHP-FPM через свою панель управления. Для полного контроля над PHP-FPM тариф VPS Хостинг с root-доступом является подходящим решением.
