Мониторинг и проверка состояния PHP-FPM
Основные методы проверки статуса PHP-FPM
Как получить детальную статистику PHP-FPM через встроенный статус?
Наиболее эффективный способ контроля работы PHP-FPM - использование встроенного механизма статуса, который активируется параметром pm.status_path в конфигурации пула. После настройки сервер будет отдавать информацию о состоянии пула (количество процессов, очереди, время работы) в формате plain text, JSON или XML.
Настройка статусного пути
Откройте конфигурационный файл пула (обычно /etc/php/8.2/fpm/pool.d/www.conf) и раскомментируйте или добавьте строку:
pm.status_path = /statusPhp fpm status (проверка статуса php-fpm)
Перезапустите PHP-FPM для применения изменений:
sudo systemctl restart php8.2-fpm
Запрос статуса через UNIX-сокет
Если PHP-FPM использует UNIX-сокет (типично для связки с Nginx), статус можно получить напрямую с помощью curl:
curl --unix-socket /var/run/php/php8.2-fpm.sock http://localhost/status?json
Параметр ?json возвращает ответ в формате JSON, что удобно для автоматизированного сбора метрик. Без него ответ будет в виде простого текста.
Типичные ошибки и их решение:
- Ошибка 404 или пустой ответ - параметр pm.status_path не установлен или указан неверно. Проверьте конфигурацию пула.
- Отказ в доступе к сокету - пользователь, от имени которого выполняется curl, не имеет прав на чтение сокета. Добавьте пользователя в группу www-data или измените права сокета (не рекомендуется в продакшене).
- Сокет не найден - уточните путь к сокету из конфигурации пула (параметр listen).
Как проверить, работает ли PHP-FPM с помощью systemctl?
Если сервер использует systemd, простейший способ убедиться в работоспособности процесса - команда systemctl status:
systemctl status php8.2-fpm
Результат покажет активность службы (active/running), PID, время работы и последние сообщения журнала. Для автоматической проверки можно использовать systemctl is-active:
systemctl is-active php8.2-fpm
В ответ вернётся active или inactive.
Ситуации, когда этот метод не подходит:
- На системах без systemd (например, CentOS 6, Debian 7) используется init-скрипт: service php-fpm status.
- Служба может быть active, но пул может быть недоступен из-за ошибок конфигурации - systemctl не покажет проблемы внутренней работы пула.
Как проверить, какие сокеты прослушивает PHP-FPM?
Для быстрой диагностики сетевых или файловых сокетов используются утилиты ss или netstat. Пример с ss:
ss -lx | grep php
Вывод покажет все UNIX-сокеты, содержащие в имени «php». Если сокет не отображается, значит PHP-FPM не запущен или настроен на TCP-сокет (тогда используйте ss -tlnp | grep php).
Возможные сложности:
- Команда ss требует прав root для просмотра всех процессов - используйте sudo.
- На старых дистрибутивах netstat может не быть установлен, его можно добавить пакетом net-tools.
Как написать PHP-скрипт для проверки статуса PM?
Когда нет доступа к командной строке или требуется интеграция с веб-интерфейсом, можно создать простой PHP-скрипт, который подключается к сокету и получает статус:
<?php
$socketPath = '/var/run/php/php8.2-fpm.sock';
$statusUrl = '/status?json';
$fp = @fsockopen('unix://' . $socketPath, -1, $errno, $errstr, 5);
if (!$fp) {
die("Ошибка подключения: $errstr ($errno)");
}
$out = "GET $statusUrl HTTP/1.0\r\nHost: localhost\r\n\r\n";
fwrite($fp, $out);
$response = '';
while (!feof($fp)) {
$response .= fgets($fp, 1024);
}
fclose($fp);
// Отделяем заголовки от тела
list($headers, $body) = explode("\r\n\r\n", $response, 2);
echo $body;
?>
Скрипт выведет JSON со всеми метриками пула. Его можно вызывать из браузера или cron для сбора данных.
Частые проблемы:
- Скрипт падает с ошибкой подключения - проверьте права на сокет и путь.
- Функция fsockopen отключена в php.ini - включите расширение sockets или используйте stream_socket_client.
Как вручную отправить HTTP-запрос к статусному сокету через socat?
Для диагностики без curl и PHP удобно использовать socat или netcat:
echo -e "GET /status HTTP/1.0\r\nHost: localhost\r\n\r\n" | socat - UNIX-CONNECT:/var/run/php/php8.2-fpm.sock
Ответ будет содержать HTTP-заголовки и тело статуса. Этот способ полезен, когда нужно быстро проверить доступность сокета из скрипта.
Примечание:
- Утилита socat может отсутствовать в системе - установите её через пакетный менеджер.
- netcat (nc) тоже поддерживает UNIX-сокеты флагом -U, но не отправляет HTTP-запрос автоматически, его придётся формировать вручную.
Как настроить Nginx для доступа к статусу PHP-FPM через веб?
Если статус нужен не только администратору, но и системам мониторинга, его можно опубликовать через веб-сервер. Пример location для Nginx:
location /fpm-status {
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /fpm-status;
allow 127.0.0.1;
deny all;
}
Теперь статус доступен по адресу http://your-server/fpm-status. Директивы allow/deny ограничивают доступ к локальному хосту для безопасности.
Типовые неполадки:
- Ошибка 404 - убедитесь, что pm.status_path в пуле совпадает с именем location (в примере /fpm-status).
- Ошибка 502 - сокет не найден или права на него у пользователя Nginx.
Как добавить проверку PHP-FPM в Zabbix?
Для системы мониторинга Zabbix можно создать UserParameter, который будет с помощью curl опрашивать статусный сокет:
UserParameter=php-fpm.status[*],curl --unix-socket /var/run/php/php8.2-fpm.sock http://localhost/status?$1 2>/dev/null | jq -r '.$2'
Параметры в скобках позволяют запрашивать отдельные метрики, например, php-fpm.status[pool,active-processes]. Скрипт требует установленного jq для парсинга JSON.
Сложности внедрения:
- Ключ должен быть добавлен в конфигурацию Zabbix агента (обычно /etc/zabbix/zabbix_agentd.conf) с последующей перезагрузкой.
- На системах с SELinux может потребоваться настройка политик для доступа к сокету.
Расширенные примеры проверки статуса PHP-FPM
Пример 1. Полная настройка pm.status_path и запрос в формате JSON с детальным выводом
Конфигурация пула (файл /etc/php/8.2/fpm/pool.d/www.conf):
; Включение статуса
pm.status_path = /status
; Доступные форматы: plain, html, json, xml (используется по умолчанию plain)
; Для json достаточно добавить ?json в URL
Перезапуск PHP-FPM:
sudo systemctl restart php8.2-fpm
Запрос статуса через UNIX-сокет с указанием нужного сокета:
curl --unix-socket /var/run/php/php8.2-fpm.sock http://localhost/status?json 2>/dev/null
Пример ответа (сокращён):
{"pool":"www","process-manager":"dynamic","start-time":1700000000,"start-since":12345,"accepted-conn":1024,"listen-queue":0,"max-listen-queue":0,"listen-queue-len":128,"idle-processes":2,"active-processes":3,"total-processes":5,"max-active-processes":10,"max-children-reached":0,"slow-requests":0}
Пояснение ключевых полей: pool - имя пула, active-processes - число обрабатываемых запросов, idle-processes - свободные процессы, listen-queue - очередь ожидающих соединений (важно для нагрузки).
Пример 2. Самодельный скрипт на PHP с обработкой ошибок и повторными попытками
<?php
function getFpmStatus($socketPath = '/var/run/php/php8.2-fpm.sock', $timeout = 3) {
$url = '/status?json';
$attempts = 3;
while ($attempts--) {
$ctx = stream_context_create(['socket' => ['timeout' => $timeout]]);
$fp = @stream_socket_client('unix://' . $socketPath, $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, $ctx);
if ($fp) {
$request = "GET $url HTTP/1.0\r\nHost: localhost\r\n\r\n";
fwrite($fp, $request);
$response = stream_get_contents($fp);
fclose($fp);
// Разделяем заголовки и тело
list($headers, $body) = explode("\r\n\r\n", $response, 2);
$data = json_decode($body, true);
if (json_last_error() === JSON_ERROR_NONE) {
return $data;
}
}
usleep(200000); // 0.2 секунды перед повтором
}
throw new Exception("Не удалось получить статус PHP-FPM: $errstr ($errno)");
}
try {
$status = getFpmStatus();
echo "Активных процессов: " . $status['active-processes'] . PHP_EOL;
echo "Свободных процессов: " . $status['idle-processes'] . PHP_EOL;
echo "Длина очереди: " . $status['listen-queue'] . PHP_EOL;
} catch (Exception $e) {
echo "Ошибка: " . $e->getMessage();
}
?>
Результат выполнения:
Активных процессов: 3 Свободных процессов: 2 Длина очереди: 0
Скрипт пригоден для использования в cron или в качестве внешнего проверяющего модуля.
Пример 3. Настройка Nginx location с ограничением доступа и проверка через браузер
# В блоке server конфигурации Nginx (обычно /etc/nginx/sites-enabled/default)
location /fpm-status {
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /fpm-status;
# Доступ только с локального IP и из доверенной подсети
allow 127.0.0.1;
allow 10.0.0.0/8;
deny all;
# Кэширование не требуется
add_header Cache-Control no-cache;
}
После перезагрузки Nginx (sudo nginx -s reload) статус становится доступен по адресу:
http://127.0.0.1/fpm-status?json
Ответ в браузере:
{"pool":"www","process-manager":"dynamic",...}
Данный метод удобен для визуального контроля и для интеграции с HTTP-проверками внешних мониторинговых систем.
Пример 4. Использование socat для нестандартных запросов
# Установка соединения с UNIX-сокетом и отправка HTTP-запроса
{ echo -e "GET /status?plain HTTP/1.0\r\nHost: localhost\r\n\r\n"; sleep 1; } | socat - UNIX-CONNECT:/var/run/php/php8.2-fpm.sock
Вывод (plain text):
HTTP/1.0 200 OK Content-Type: text/plain;charset=utf-8 ... pool: www process manager: dynamic start time: ... start since: 12345 accepted conn: 1024 listen queue: 0 max listen queue: 0 listen queue len: 128 idle processes: 2 active processes: 3 total processes: 5 max active processes: 10 max children reached: 0 slow requests: 0
Такой вывод легко парсится grep и awk для извлечения конкретных полей.
Пример 5. Интеграция с Prometheus через php-fpm_exporter
# Запуск экспортёра (предварительно установить из репозитория)
php-fpm-exporter --endpoint http://127.0.0.1/fpm-status?json --web.listen-address=:9253
# Метрики доступны на http://localhost:9253/metrics
Пример метрик в Prometheus:
# HELP php_fpm_up Was the last scrape of php-fpm successful.
# TYPE php_fpm_up gauge
php_fpm_up{pool="www"} 1
# HELP php_fpm_active_processes The number of active processes.
# TYPE php_fpm_active_processes gauge
php_fpm_active_processes{pool="www"} 3
# HELP php_fpm_idle_processes The number of idle processes.
# TYPE php_fpm_idle_processes gauge
php_fpm_idle_processes{pool="www"} 2
...
Это решение подходит для масштабного сбора метрик и визуализации в Grafana.