Эксплуатация API
Health check OpenAI-совместимого API: что проверять
Health check OpenAI-совместимого API должен отвечать на конкретный вопрос: жив ли процесс, готово ли приложение обслуживать трафик или проходит ли реальный синтетический сценарий. Если смешать эти уровни, один временный сбой внешнего маршрута перезапустит здоровый сервис, а мониторинг начнёт тратить бюджет и создавать лишнюю нагрузку.
Короткий ответ: разделите liveness, readiness и synthetic check
Liveness показывает, что процесс приложения не завис и способен ответить локально. Readiness показывает, что приложение получило конфигурацию, может обратиться к необходимым внутренним зависимостям и готово принимать пользовательский трафик. Synthetic check — отдельная ограниченная проверка настоящей интеграции: endpoint, собственный ключ, выбранный маршрут и минимальный контракт ответа.
Разделение особенно важно для AI API. Перезапуск контейнера редко исправляет неверный ключ, превышенный лимит, ошибку модели или временный сбой сети. И наоборот: зависшая база или отсутствующая переменная окружения должны сделать приложение неготовым, даже если внешний API сейчас отвечает. Такая схема даёт операторам точную причину и предотвращает каскадные рестарты.
Что должен и не должен делать каждый уровень
| Проверка | Допустимая работа | Чего не делать |
|---|---|---|
| Liveness | Вернуть 200 от работающего процесса за 1–2 секунды. | Не вызывать базу, очередь или AI API. |
| Readiness | Проверить обязательную конфигурацию и внутренние зависимости с коротким deadline. | Не отправлять полноценный пользовательский prompt. |
| Synthetic | Редко проверить один выбранный сценарий и зафиксировать метрики. | Не запускать на каждом запросе и не печатать секреты. |
Не используйте один URL вроде /health для всего. Оркестратор может трактовать его как сигнал для рестарта, балансировщик — как готовность, а дежурный — как доступность функции. Отдайте раздельные endpoint: например, /health/live и /health/ready. Синтетическую проверку запускайте из контролируемого мониторинга или очереди, а результат храните отдельно от пользовательских запросов.
Readiness начинается с безопасной конфигурации
Перед первым сетевым вызовом приложение должно убедиться, что есть обязательные переменные: endpoint, имя выбранной модели, собственный RUSSIAAPI_API_KEY и конфигурация deadline. Проверка подтверждает наличие, но никогда не возвращает значение секрета. Ошибка должна называться по типу: missing_api_key, invalid_base_url или catalog_not_configured. Не выводите полный объект process.env в ответ или лог.
Модель не стоит жёстко привязывать к тексту статьи или Docker image. В текущем аккаунте сначала посмотрите каталог и права, затем сохраните разрешённое имя в конфигурации. Как безопасно проверить список моделей и endpoint, описывает руководство по /v1/models. Если readiness зависит от базы или очереди, дайте каждой проверке свой deadline, например 500–1000 мс, и возвращайте 503 только при реальной невозможности принять работу.
Минимальный пример endpoint
Этот Node.js пример создаёт локальные проверки. Он не вызывает модель и поэтому не подтверждает доступность внешнего маршрута; это намеренное ограничение. В production добавьте аутентификацию или сетевое ограничение для технических endpoint, если их статус раскрывает внутреннюю топологию.
app.get('/health/live', (_req, res) => {
res.status(200).json({ status: 'ok' });
});
app.get('/health/ready', async (_req, res) => {
const configured = Boolean(process.env.RUSSIAAPI_API_KEY) &&
Boolean(process.env.RUSSIAAPI_MODEL);
if (!configured) return res.status(503).json({ status: 'not_ready', reason: 'config' });
const dbOk = await pingDatabase({ timeoutMs: 800 });
return dbOk
? res.status(200).json({ status: 'ready' })
: res.status(503).json({ status: 'not_ready', reason: 'database' });
});В этот код не следует добавлять console.log(process.env), значение ключа или тестовый prompt. Если база недоступна, проверка должна завершаться по deadline, а не зависать вместе с процессом. Если несколько зависимостей важны по-разному, обозначьте это явно: например, без очереди нельзя принять видео-задачу, но можно ответить на короткий чат. Такой выбор — продуктовая политика, которую надо документировать и тестировать.
Как сделать синтетическую проверку маршрута
Синтетическая проверка должна быть дешёвой, предсказуемой и отделённой от пользовательского трафика. Выберите отдельный собственный ключ или контролируемый идентификатор мониторинга, минимальный безопасный вход и конкретный ожидаемый признак: HTTP-статус, ответ с валидным JSON либо отсутствие определённой ошибки. Не превращайте ответ модели в жёсткое сравнение длинного текста: генерация вероятностна, а тест нужен для контракта, не для художественной оценки.
Запускайте её с разумной частотой и бюджетом. Например, раз в 5 или 15 минут для критичного маршрута может быть достаточно после замера расхода; точная частота зависит от SLA, лимита и стоимости. При сбое сохраняйте безопасные метаданные: внутренний request ID, время, маршрут, класс ошибки, HTTP-статус и задержку. Ни key, ни Authorization, ни пользовательский текст в такую запись не входят. Общие правила безопасных логов приведены в статье о хранении API Key.
Ошибки не равны недоступности
Код 401 или 403 говорит, что надо проверить собственный ключ, endpoint и права; он не повод бесконечно перезапускать контейнер. Код 429 требует контролировать конкурентность и повторять лишь по согласованной политике. Тайм-аут может быть сетевой проблемой, слишком маленьким deadline или зависшей очередью. Разделяйте эти причины в метриках, иначе alert «API down» ничего не объяснит. Для безопасного разбора доступа используйте чек-лист 401/403, а для временных ограничений — разбор 429 и backoff.
При серии временных отказов не заставляйте synthetic check усугублять проблему. Объедините его с лимитом попыток и circuit breaker: откройте маршрут на короткий период, запишите состояние и выполните одну пробу после паузы. Пользовательский endpoint в это время возвращает честный статус или помещает несрочную работу в очередь. Такая политика описана подробнее в руководстве по circuit breaker.
Наблюдаемость, которая помогает дежурному
Дашборд полезен тогда, когда по нему можно решить, что делать. Показывайте отдельно: доступность liveness, readiness, успешность synthetic check, p50/p95 задержку, частоту 401/403, 429, 5xx и тайм-аутов, число открытий breaker и длину очереди. Для расходов добавьте стоимость успешной синтетической или пользовательской задачи, но не склеивайте их: мониторинговый трафик должен быть виден отдельно.
У каждого alert должны быть владелец, окно, порог и runbook. Пример: «три synthetic check подряд получили timeout за 10 минут» — проверить сеть, историю релиза и breaker; «readiness не проходит из-за конфигурации» — откатить секретную переменную или rollout. Не обещайте доступность на основании одного HTTP 200. Наблюдаемость подтверждает состояние в заданный момент, а не заменяет контракт, резервирование и тесты.
Проверочный список перед production
- Создайте отдельные
/health/liveи/health/ready, определив, что именно они проверяют. - Проверьте отсутствие обязательной переменной, недоступную базу, сетевой timeout, 401, 429 и 5xx.
- Выберите минимальный синтетический сценарий, отдельный бюджет и безопасные поля лога.
- Убедитесь, что health endpoint не выдаёт секреты, каталог моделей или полный стек внешнему пользователю.
- Выпустите изменения на малую долю трафика и оставьте rollback; тестируйте интеграцию перед rollout.
Контрактный набор нужен не только для проверки здоровья. Он показывает, сохранились ли необходимые поля ответа, корректно ли обрабатываются ошибки и не изменился ли выбранный маршрут. Пример такого набора и controlled rollout разобран в тестировании OpenAI-совместимого API.
Постройте проверку на текущем каталоге
Откройте документацию RussiaAPI, выберите доступную модель в консоли и начните с локального readiness endpoint. Затем добавьте ограниченную синтетическую проверку с собственным серверным ключом и безопасными метриками.
FAQ
Нужно ли health check всегда вызывать модель?
Нет. Liveness проверяет процесс, readiness — локальную готовность. Вызов модели — отдельная редкая синтетическая проверка с бюджетом и минимальным безопасным входом, иначе мониторинг создаст нагрузку и расходы.
Достаточно ли /v1/models для проверки?
Нет. Он может подтвердить endpoint и права собственного ключа, но не гарантирует работу конкретной модели, формат ответа или весь пользовательский сценарий. Добавьте контрактный тест.
Что сохранять в логах проверки?
Время, внутренний request ID, тип проверки, HTTP-статус, задержку и безопасный класс ошибки. Не сохраняйте Authorization, API key, cookie, полный prompt, ответ или все переменные окружения.