Skip to content

Метрики и проверки состояния ​

Секция [observability] запускает ещё один процесс, который отдаёт пробы состояния и метрики Prometheus. Этот процесс не выполняет PHP. Он читает состояние воркеров PHP из общей памяти. Мастер контролирует, перезагружает и останавливает этот процесс вместе с воркерами PHP. Мастер и его воркеры описаны в разделе Модель процессов.

Без секции [observability] Rapira не запускает этот процесс. Сборка для Windows не поддерживает эту секцию и отвергает её как неизвестное поле.

Включение эндпоинтов ​

Добавьте секцию [observability] и хотя бы одну из её подтаблиц. Конфигурация также должна содержать [http] или [grpc]. Этот минимальный rapira.toml включает все эндпоинты:

toml
[http]
listen = "127.0.0.1:8000"

[http.pool]
entrypoint = "index.php"

[observability]
listen = "127.0.0.1:9180"

[observability.metrics]   # GET /metrics

[observability.probes]    # GET /livez и GET /readyz

[observability.metrics] и [observability.probes] не принимают ключей. Укажите адрес listen, который не используют слушатели http и grpc. Все ключи описаны в разделе Секция [observability].

Запустите сервер. Затем отправьте запрос на каждый эндпоинт:

bash
curl -i http://127.0.0.1:9180/livez
curl -i http://127.0.0.1:9180/readyz
curl http://127.0.0.1:9180/metrics

Процесс пишет записи лога с целью observability. Уровни для целей описаны в разделе Логирование.

Эндпоинты ​

Процесс обслуживает HTTP/1.1 без TLS. Он отвечает только на эти запросы:

ЗапросВключаетСтатусТело
GET /livez[observability.probes]Всегда 200ok
GET /readyz[observability.probes]200 или 503ok или по одной строке pool <name>: no ready worker для каждого пула, который не готов
GET /metrics[observability.metrics]200Текстовый формат Prometheus

Любой другой метод или путь получает 404 с пустым телом. Путь выключенной подтаблицы тоже получает 404. Каждая строка тела заканчивается переводом строки. Пробы используют тип содержимого text/plain; charset=utf-8. /metrics использует text/plain; version=0.0.4; charset=utf-8.

Живость и готовность ​

/livez не выполняет проверок. Он возвращает 200, когда процесс отвечает. Когда мастер останавливается, процесс observability тоже останавливается. Поэтому ответ 200 показывает, что мастер работает. Мастер сам заменяет упавшие воркеры PHP, поэтому /livez их не проверяет.

/readyz проверяет каждый пул PHP: сначала http, затем grpc. Пул готов, когда хотя бы один его воркер простаивает или занят запросом. Воркеры, которые запускаются или завершают работу, не учитываются. /readyz возвращает 503 в этих случаях:

  • Воркеры пула запускаются и ещё не ожидают запрос. В режимах Worker и Dispatcher входной скрипт сначала должен инициализироваться.
  • Входной скрипт не может инициализироваться. Воркер повторяет попытку, и пул становится готовым после успешной инициализации. Запрос для этого не нужен.
  • Перезагрузка запускает новые воркеры, которые не могут инициализироваться. После process_control_timeout_secs мастер всё равно останавливает старые воркеры.
  • Короткое время каждый воркер пула завершает работу, например после max_requests, и ни одна замена ещё не ожидает запрос.

Обычная перезагрузка оставляет /readyz в состоянии 200. Мастер запускает новый воркер до остановки старого. Последовательность перезагрузки описана в разделе Сигналы.

В некоторых случаях ответа нет совсем. В начале остановки процесс observability перестаёт принимать соединения. Если воркеры пула не могут инициализироваться до того, как пул обслужит запрос, мастер завершается с кодом 70. Подробнее - в разделе Коды завершения.

Пробы Kubernetes ​

Kubelet отправляет пробы на IP-адрес пода, поэтому петлевой адрес не работает. Привяжите слушатель ко всем интерфейсам пода. Не добавляйте порт в Service.

toml
[observability]
listen = ":9180"

[observability.probes]
yaml
containers:
  - name: app
    image: registry.example.com/app:latest
    livenessProbe:
      httpGet:
        path: /livez
        port: 9180
      periodSeconds: 10
    readinessProbe:
      httpGet:
        path: /readyz
        port: 9180
      periodSeconds: 5

Метрики Prometheus ​

Сервер Prometheus на том же хосте может собирать метрики с петлевого адреса. Prometheus использует /metrics как metrics_path по умолчанию.

yaml
scrape_configs:
  - job_name: rapira
    static_configs:
      - targets: ["127.0.0.1:9180"]

Вывод содержит эти метрики. Метка pool имеет значение http или grpc. Метрики не включают процесс observability. Единица работы - это один HTTP-запрос или один вызов gRPC.

МетрикаТипМеткиЗначение
rapira_workersgaugepool, stateВоркеры в каждом состоянии. Значения state: starting, idle, active и draining.
rapira_workers_configuredgaugepoolЗначение processes пула.
rapira_requests_totalcounterpoolЕдиницы работы, которые воркеры завершили. Неудачные единицы включены.
rapira_requests_failed_totalcounterpoolЕдиницы работы, которые хост не смог завершить, например потерянный вызов или отказ после переполнения очереди.
rapira_requests_failed_on_full_queue_totalcounterpoolЕдиницы работы, которые застали очередь воркера полной и не попали в неё. Rapira отклоняет такую единицу, когда очередь остаётся полной 30 секунд.
rapira_requests_queuedgaugepoolЕдиницы работы, которые ожидают PHP-поток воркера.
rapira_script_restarts_totalcounterpoolПерезапуски входного скрипта внутри процесса воркера, например после фатальной ошибки.
rapira_worker_exits_totalcounterpool, reasonЗавершения процессов воркеров. Причины описаны ниже.
rapira_worker_rss_bytesgaugepool, workerРезидентная память воркера в байтах. Только Linux.
rapira_worker_pss_bytesgaugepool, workerПропорциональная память воркера в байтах. Только Linux.
rapira_build_infogaugeversion, php_versionВерсия Rapira и версия связанного PHP. Значение всегда 1.

Счётчики запросов описывают работу PHP, а не весь трафик слушателя. Они исключают отказы аутентификации, некорректные JSON-запросы, проверки состояния и рефлексию, которые протокольный слой обрабатывает до передачи в PHP. Хост считает завершённый ответ gRPC fail() обработанным без ошибки хоста. Последующая ошибка преобразования ответа в JSON не увеличивает счётчик ошибок. Поэтому rapira_requests_failed_total не считает статусы gRPC, отличные от OK.

Метка reason метрики rapira_worker_exits_total имеет эти значения:

ПричинаЗначение
drainedВоркер завершился с кодом 0, например после остановки или перезагрузки.
recycledВоркер достиг max_requests.
unhealthyВоркер сообщил, что не может обслуживать запросы, например после повторных неудачных инициализаций.
timeoutЗапрос выполнялся дольше request_terminate_timeout_secs, и мастер остановил воркер.
crashedВоркер завершился с другим кодом или из-за сигнала.

Счётчики сохраняют значения, когда мастер заменяет или перезагружает воркер. Они сбрасываются в ноль только при новом запуске мастера. Сбор метрик читает один файл /proc для каждого работающего воркера. Пробы не читают файлов.

Почему метка worker не является ID процесса?

Метка worker - это номер слота воркера в его пуле. Заменяющий воркер может использовать тот же слот, поэтому ряды продолжаются после замены. Каждый пул имеет два слота на каждый воркер. Поэтому номера идут от 0 до удвоенного processes минус один.

Почему пул показывает больше воркеров, чем rapira_workers_configured?

Во время перезагрузки мастер запускает новый воркер до остановки старого. Оба воркера видны в rapira_workers, пока старый воркер не завершится.

Безопасность ​

Эндпоинты не используют аутентификацию и TLS. /metrics показывает версии Rapira и PHP и память каждого воркера. Привяжите слушатель к петлевому адресу или к адресу частной сети. Адрес вида :port привязывается ко всем интерфейсам IPv4.

Слушатель unix: создаёт сокет с правами 0666. Управляйте доступом через права каталога сокета.

Настройка для продакшена описана в разделе Запуск в продакшене.