Как да рестартирате 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 сигнали. Този метод заобикаля изцяло init системата и ви дава прецизен, нискониво контрол — от съществено значение в контейнеризирани среди, персонализирани init системи или когато `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` | Средно — прекъсва активни връзки | Стандартни промени в конфигурацията, разработка/тестване |
| `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>` чрез entrypoint скрипт |
| Проверка на синтаксиса на конфигурацията преди прилагане | Първо `php-fpm<ver> -t`, след това презареждане/рестартиране |
ЧЗВ
Каква е разликата между `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 достъп е подходящото решение.
