К содержанию
ActionPulse

Проверки работоспособности

Служебный путь проверки есть у обоих сервисов 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-балансировщиком:

  • Основной APIGET /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 подходит для балансировщика и оркестратора и не подходит как единственный монитор установки. Дежурный смотрит на метрики и правила, балансировщик — на этот путь.