Проверки работоспособности
Служебный путь проверки есть у обоих сервисов ActionPulse и отвечает у каждого за своё. Что означает 503, как настроить балансировщик и оркестратор, чего проверка не покрывает.
На этой странице
У установки два независимых HTTP-сервиса, и служебный путь /healthz есть у
обоих. Отвечает он у каждого за своё, поэтому «проверка прошла» без указания
сервиса — бессмысленное утверждение. Ниже — точные условия готовности, как
подключить проверку к балансировщику и оркестратору и что она не покрывает.
Что именно проверяет каждый сервис
/healthz лежит в корне сервиса, а не под /api/v1, не требует ключа и
не зависит от лицензии. Ответ 200 всегда содержит тело {"status":"ok"}.
| Сервис | Порт в контейнере | Условие ответа 200 |
Ответ при отказе |
|---|---|---|---|
Основной API (query-api) |
8080 |
успешный ping PostgreSQL | 503, сообщение postgres unavailable |
Приём событий (ingest-api) |
8081 |
соединение с NATS активно | 503, сообщение nats disconnected |
Ответ 503 приходит в обычном конверте ошибки с кодом internal:
{ "error": { "code": "internal", "message": "postgres unavailable", "details": {} } }
Других служебных путей нет: /readyz и /livez в продукте не существуют, и
проверка одна на готовность и на живость.
Что означает неготовность
503 от основного API означает, что недоступна PostgreSQL. В этом состоянии не
работает ничего: ни вход в кабинет, ни отчёты, ни настройки. Это отказ, а не
деградация.
503 от приёма событий означает, что потеряно соединение с NATS — сервис не
может опубликовать событие и поэтому не принимает его. Данные при этом не
теряются, если клиент повторяет запрос: ответ приёма ничего не подтверждает до
записи в очередь. Библиотека в браузере и серверные клиенты обязаны повторять
запрос с той же полезной нагрузкой и тем же event_id — дедупликация не даст
дублей.
Оба сервиса отвечают 503 до того, как отработает прикладная логика, поэтому
безопасно снимать трафик по этому признаку: балансировщик просто перестаёт
отдавать запросы неготовому экземпляру.
Проверки в балансировщике
Что настроить перед своим reverse proxy или L4-балансировщиком:
- Основной API —
GET /healthzна порт8080, ожидать200. - Приём событий —
GET /healthzна порт8081, ожидать200. Это отдельная проверка отдельного пула, а не копия предыдущей. - Интервал 5–10 секунд, таймаут заметно меньше интервала, порог вывода из
ротации — 2–3 подряд неуспешных ответа. Одиночный
503во время перезапуска PostgreSQL не должен снимать весь пул. - Проверку выполняйте по HTTP внутри контура, без клиентских сертификатов и заголовков авторизации: путь публичный и не аутентифицирован.
- Не выставляйте
/healthzнаружу как единственную «страницу состояния» — ответ намеренно минимален и не содержит версий и внутренних адресов, но и пользы для внешнего наблюдателя в нём нет.
Проверки в оркестраторе
Docker Compose. В поставляемом файле проверка задана у query-api
(интервал 5 с, таймаут 3 с, до 30 попыток) и у хранилищ: PostgreSQL через
pg_isready, ClickHouse через тестовый запрос, Redis ожидает ответ NOAUTH
(обычный PONG считается ошибкой конфигурации, потому что означает доступного
анонимного пользователя), NATS — через свой служебный путь, Elasticsearch — через
состояние кластера по TLS. Порядок запуска задан зависимостями: одноразовые
контейнеры миграции и создания потоков должны завершиться успешно, иначе
долгоживущие сервисы не стартуют.
У ingest-api в поставляемом Compose проверки нет. Если вам нужно, чтобы
состояние контейнера отражало готовность приёма, добавьте её сами — путь и порт
те же:
# из каталога комплекта: разовая проверка приёма событий изнутри контура
docker compose -f docker-compose.onprem.yml --env-file .env \
exec ingest-api wget -qO- http://localhost:8081/healthz
Kubernetes. Чарт задаёт readinessProbe с httpGet на /healthz и
порт сервиса для ingest-api и query-api: задержка перед первой проверкой
5 секунд, интервал 10. Liveness-проба не задаётся намеренно — перезапуск пода
из-за недоступной базы данных не ускоряет восстановление, а усугубляет его.
Ручной чеклист «установка жива»
Выполняется из каталога распакованного комплекта, занимает пару минут.
# 1. Ни один контейнер не перезапускается по кругу
docker compose -f docker-compose.onprem.yml --env-file .env ps
# 2. Основной API отвечает через публичный адрес (проверяется и Caddy, и TLS)
curl -fsS "https://${PP_DOMAIN}/healthz"
# 3. Приём событий отвечает внутри контура
docker compose -f docker-compose.onprem.yml --env-file .env \
exec ingest-api wget -qO- http://localhost:8081/healthz
# 4. Одноразовые контейнеры завершились успешно, а не упали
docker compose -f docker-compose.onprem.yml --env-file .env \
ps -a query-api-migrate query-api-nats-bootstrap
# 5. Лицензия действует и разрешает запись
curl -fsS "https://${PP_DOMAIN}/api/v1/license" \
-H "Authorization: Bearer $TOKEN"
# 6. Прикладные метрики отдаются
docker compose -f docker-compose.onprem.yml --env-file .env \
exec query-api wget -qO- http://localhost:9090/metrics | grep -c '^pp_'
Токен доступа для шага 5 получают обычным входом в кабинет; он живёт 15 минут.
Признак «всё хорошо»: шаги 2 и 3 отвечают {"status":"ok"}, шаг 4 показывает
код завершения 0 у обоих одноразовых контейнеров, шаг 5 возвращает
"valid": true и "read_only": false.
Полная проверка сквозного пути — отправить тестовое событие и увидеть его в живом потоке проекта. Служебная проверка этого не делает и сделать не может.
Чего эти проверки не проверяют
/healthz — узкий сигнал по одной зависимости на сервис. Он не покрывает:
- ClickHouse и Redis. Основной API ответит
200при недоступном ClickHouse: отчёты будут падать, проверка — нет. - Приём событий, когда очередь жива, а запись нет.
ch-writerможет отставать или не писать в ClickHouse вовсе — это видно только по отставанию и по очереди недоставленных сообщений. - Лицензию. Установка без действующей лицензии отвечает
200на проверку и403на любую запись, включая приём событий. - Воркер. У
workerнет HTTP-поверхности и нет служебного пути. Его остановка не влияет на проверки, но останавливает задачи по расписанию, а через две минуты — и приём событий, потому что перестаёт обновляться проекция лицензии. - Миграции. Проверка не различает применённую и неприменённую схему.
Гарантию даёт успешное завершение одноразового контейнера миграции, а не
ответ
200. - Место на диске, состояние резервных копий, доставку журналов и оповещений. Это зона наблюдаемости.
Практический вывод: /healthz подходит для балансировщика и оркестратора и
не подходит как единственный монитор установки. Дежурный смотрит на метрики и
правила, балансировщик — на этот путь.