Метрики и проверки состояния
Секция [observability] запускает ещё один процесс, который отдаёт пробы состояния и метрики Prometheus. Этот процесс не выполняет PHP. Он читает состояние воркеров PHP из общей памяти. Мастер контролирует, перезагружает и останавливает этот процесс вместе с воркерами PHP. Мастер и его воркеры описаны в разделе Модель процессов.
Без секции [observability] Rapira не запускает этот процесс. Сборка для Windows не поддерживает эту секцию и отвергает её как неизвестное поле.
Включение эндпоинтов
Добавьте секцию [observability] и хотя бы одну из её подтаблиц. Конфигурация также должна содержать [http] или [grpc]. Этот минимальный rapira.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].
Запустите сервер. Затем отправьте запрос на каждый эндпоинт:
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] | Всегда 200 | ok |
GET /readyz | [observability.probes] | 200 или 503 | ok или по одной строке 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.
[observability]
listen = ":9180"
[observability.probes]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 по умолчанию.
scrape_configs:
- job_name: rapira
static_configs:
- targets: ["127.0.0.1:9180"]Вывод содержит эти метрики. Метка pool имеет значение http или grpc. Метрики не включают процесс observability. Единица работы - это один HTTP-запрос или один вызов gRPC.
| Метрика | Тип | Метки | Значение |
|---|---|---|---|
rapira_workers | gauge | pool, state | Воркеры в каждом состоянии. Значения state: starting, idle, active и draining. |
rapira_workers_configured | gauge | pool | Значение processes пула. |
rapira_requests_total | counter | pool | Единицы работы, которые воркеры завершили. Неудачные единицы включены. |
rapira_requests_failed_total | counter | pool | Единицы работы, которые хост не смог завершить, например потерянный вызов или отказ после переполнения очереди. |
rapira_requests_failed_on_full_queue_total | counter | pool | Единицы работы, которые застали очередь воркера полной и не попали в неё. Rapira отклоняет такую единицу, когда очередь остаётся полной 30 секунд. |
rapira_requests_queued | gauge | pool | Единицы работы, которые ожидают PHP-поток воркера. |
rapira_script_restarts_total | counter | pool | Перезапуски входного скрипта внутри процесса воркера, например после фатальной ошибки. |
rapira_worker_exits_total | counter | pool, reason | Завершения процессов воркеров. Причины описаны ниже. |
rapira_worker_rss_bytes | gauge | pool, worker | Резидентная память воркера в байтах. Только Linux. |
rapira_worker_pss_bytes | gauge | pool, worker | Пропорциональная память воркера в байтах. Только Linux. |
rapira_build_info | gauge | version, 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. Управляйте доступом через права каталога сокета.
Настройка для продакшена описана в разделе Запуск в продакшене.