Мониторинг и проверка состояния PHP-FPM

Раздел: Администрирование сервера -> Мониторинг 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 = /status

Php 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.

Проверка статуса PHP-FPM - comments

En
Php fpm status (php)