GH GambleHub

Liveness/Readiness пробы

2) Принципы дизайна

1. Разделяйте семантики.

Readiness: внешняя способность обслужить запросы (учитывает критичные зависимости).
Liveness: детект «неизлечимого» состояния процесса.
2. Fail-fast, но не «false-fast». Настройте таймауты/порог `failureThreshold` так, чтобы короткие всплески не приводили к лишним рестартам.
3. Никаких тяжелых операций в пробах. Проверка должна быть быстрой (≤100–200 мс) и без побочных эффектов.
4. Грациозная деградация. При частичной недоступности зависимостей — Readiness=OK, если есть безопасный фоллбек (кэш/огрубление).
5. Deterministic I/O. Статусы зависят только от текущего состояния, а не от «случайных» внешних тестов.

3) Семантика HEALTH-эндпоинтов

3.1 HTTP-подход (рекомендуется)

`GET /healthz/liveness` → 200 если процесс «жив» (event-loop крутится, GC не застрял, watchdog «сердце» бьется).
`GET /healthz/readiness` → 200 если экземпляр готов к трафику критичного класса. Проверки: пул соединений, локальные кэши, доступность ядра бизнес-логики.
`GET /healthz/startup` → 200 после инициализации (миграции/прогрев кэша/загрузка моделей).

Правила:
  • Нельзя в liveness ходить в внешние БД/API — это приведет к «самоубийствам» во время инцидентов зависимостей.
  • В readiness можно проверять критичные зависимости, но с таймаутами и деградацией: если есть валидный фоллбек — не валить.

3.2 gRPC Health Checking

Используйте стандарт `grpc.health.v1.Health/Check` с service-scoped состояниями (`SERVING`, `NOT_SERVING`). Для Kubernetes — grpc-пробы (или http-прокси).

3.3 Внутренние триггеры

Watchdog «мягкой» остановки: при SIGTERM выставлять Readiness=FAIL → выжидать `terminationGracePeriodSeconds` → завершаться, отрабатывая очереди.

4) Тайминги и пороги (tuning)

Ключевые поля Kubernetes-проб:
  • `initialDelaySeconds`, `periodSeconds`, `timeoutSeconds`, `successThreshold`, `failureThreshold`.
Рекомендации по стартовым профилям: Web/API с быстрым стартом:
  • readiness: `period=5s, timeout=0.2–0.5s, failure=2`
  • liveness: `period=10s, timeout=0.2–0.5s, failure=3`
Тяжелый старт (JIT/модели/прогрев):
  • startup: `period=5s, failure=60` (до ~5 мин)
  • readiness/liveness активируются после успеха startup
Batch/consumer:
  • readiness отражает готовность к обработке (подключение к брокеру, есть ли DLQ-деградация),
  • liveness — внутренний heartbeat loop.

Бэкоф на отказах: в приложении используйте экспоненциальный backoff на переподключение к зависимостям, иначе readiness будет «пилить».

5) Конфигурации (фрагменты)

5.1 Kubernetes, HTTP-пробы

yaml livenessProbe:
httpGet: { path: /healthz/liveness, port: 8080 }
periodSeconds: 10 timeoutSeconds: 1 failureThreshold: 3

readinessProbe:
httpGet: { path: /healthz/readiness, port: 8080 }
periodSeconds: 5 timeoutSeconds: 1 failureThreshold: 2

startupProbe:
httpGet: { path: /healthz/startup, port: 8080 }
periodSeconds: 5 failureThreshold: 60

5.2 Kubernetes, gRPC-проба

yaml readinessProbe:
grpc:
port: 9090 service: my. app. Service periodSeconds: 5 timeoutSeconds: 1

5.3 Graceful shutdown

yaml terminationGracePeriodSeconds: 30 lifecycle:
preStop:
exec:
command: ["/bin/sh","-c","curl -s localhost:8080/healthz/drain && sleep 5"]

`/healthz/drain` внутри сервиса переводит Readiness=FAIL (stop-accepting), дает времени завершить активные запросы.

6) Зависимости и деградация

Критичные (без них нельзя обслужить): БД авторизации для `/login`, платежный шлюз для `/pay`. Можно проверять в readiness с таймаутом ≤80% от `timeoutSeconds` пробы.
Некритичные: аналитика, email, кэш-слой при наличии догруза. Не включайте их в readiness; используйте фоллбек.
Feature-flags: при частичной деградации отключайте зависимые фичи, сохраняя Readiness=OK.

7) Очереди и фоновые обработчики

Consumers/Workers:
  • Readiness=OK, если подписка/коннект к брокеру установлен и есть ресурс для обработки.
  • При переполнении DLQ/лаге → Readiness может оставаться OK (если принимаем и складываем), но SLI «свежесть/лаг» загорается — алерт по данным.
  • Liveness: контролируйте poll-цикл/heartbeat, дедлок-детектор.

Идемпотентность: ускоряет восстановление после рестартов liveness.

8) Sidecar/mesh/ingress

При использовании service mesh (Istio/Linkerd) probe может идти через sidecar:
  • Включите `readinessGate` (K8s) для учета статуса sidecar,
  • Убедитесь, что пробы не попадают в mTLS-барьеры (или добавьте исключения).
  • Ingress/Envoy/Nginx: проксируйте `/healthz/` локально, не «выводите наружу» внутренние детали.

9) Безопасность и приватность

Health-эндпоинты не должны раскрывать конфиги, версии библиотек, строки ошибок — только «OK/FAIL» + минимальный код причины.
Доступ извне ограничьте (NetworkPolicy/ACL). Для публичных — давайте только liveness-пинг без деталей.
Логи health-проверок — на уровне DEBUG, с троттлингом.

10) Наблюдаемость и SLO

Экспортируйте метрики: `health_readiness{status}`, `health_liveness{status}`, время обработки пробы.
Связывайте Readiness-флапы с SLO доступности (выпадение из эндпоинтов → 5xx/connection reset).

Алерты:
  • «Частые рестарты по liveness > N/час» — симптом дедлоков/утечек.
  • «Флап Readiness > X/15 мин» — симптом зависимости/сетевых проблем.
  • Корреляция с деплоем (`service.version`).

11) Тестирование

Unit/Contract: эндпоинты `/healthz/` возвращают корректные статусы при выключении каждой зависимости.
Chaos: отключение БД/кэша/брокера: Readiness должен падать или включать фоллбек строго по модели. Liveness — не триггерится, если процесс «жив».
Load/Soak: под нагрузкой health-эндпоинты должны оставаться быстрыми (не пробрасывать контеншн).
Canary: проверяйте стабильность Readiness перед увеличением трафика.

12) Частые ошибки и как их избежать

Liveness проверяет БД/внешние API. Итог — бесконечные рестарты при инцидентах. Решение: ограничить liveness «жизнью процесса».
Тяжелые проверки в пробах. Ведет к ложным отказам. Решение: легкие проверки + отдельные background-health мониторы.
Нет Startup Probe. Медленные старты «убиваются» liveness. Решение: добавить startup с широким окном.
Отсутствие graceful shutdown. Редкие 5xx при деплое. Решение: preStop + снятие из балансировки.
Флап-штормы. Слишком агрессивные пороги. Решение: поднять `failureThreshold`, увеличить `timeoutSeconds`, добавить backoff.
Одинаковые эндпоинты для всего. Смешение семантик. Решение: отдельные `liveness/readiness/startup`.

13) Мини-паттерны реализации

Простой HTTP-хэндлер (псевдокод):
python
@app. get("/healthz/liveness")
def liveness():
return 200

@app. get("/healthz/readiness")
def readiness():
ok_core = core_is_ready () # local pools/caches/initialization ok_db = db. ping (timeout = 50 _ ms) # only if the DB is critical return 200 if (ok_core and ok_db) else 503

@app. get("/healthz/startup")
def startup():
return 200 if INIT_DONE else 503

@app. post("/healthz/drain")
def drain():
set_readiness(False); return 200
gRPC health (идея):
go
// use google. golang. org/grpc/health/grpc_health_v1 healthServer. SetServingStatus("my. app. Service", SERVING) // or NOT_SERVING
ReadinessGate (истина с mesh):
yaml spec:
readinessGates:
- conditionType: "proxy. istio. io/ready"

14) Чек-листы

Перед продом

  • Разделены эндпоинты liveness/readiness/startup, описана их семантика.
  • Liveness не трогает внешние зависимости; Readiness проверяет только критичные с таймаутами и фоллбеком.
  • Настроены `initialDelay/period/timeout/failureThreshold` под профиль сервиса.
  • Включен graceful shutdown: `preStop` + снятие из балансировки.
  • Метрики/логи здоровья подключены; алерты на рестарты/флап.
  • Тесты отказов зависимостей и медленных стартов пройдены.

Эксплуатация

  • Еженедельный отчет по рестартам и флапам readiness.
  • Тюнинг порогов после инцидентов; связь с релизами.
  • Регулярные chaos-тесты выключения зависимостей.
  • Актуальность семантик при изменении критичности зависимостей.

15) FAQ

В: Можно ли одной пробой закрыть все?
О: Нежелательно. Разделяйте `startup`, `readiness`, `liveness` — это снижает ложные срабатывания и ускоряет RCA.

В: Проверять ли кэш в readiness?
О: Если без кэша есть корректный (хоть и медленнейший) режим — не валите readiness, просто включите деградацию.

В: Что делать при частых рестартах по liveness?
О: Сначала исключите дедлок/утечку; затем ослабьте пороги и добавьте watchdog в приложении.

В: Как учесть многоарендность?
О: Readiness должен отражать способность обслужить любой аренда-трафик. Для частных проблем конкретного арендатора — не меняйте readiness, а сигнализируйте отдельными SLI/алертами.

Связанные материалы:
  • «Наблюдаемость: логи, метрики, трассировки»
  • «Распределенные трассировки»
  • «SLO/SLA и метрики»
  • «Гарантии доставки вебхуков»
  • «Шифрование In Transit»
  • «Менеджмент секретов»
Contact

Свяжитесь с нами

Обращайтесь по любым вопросам или за поддержкой.Мы всегда готовы помочь!

Telegram
@Gamble_GC
Начать интеграцию

Email — обязателен. Telegram или WhatsApp — по желанию.

Ваше имя необязательно
Email необязательно
Тема необязательно
Сообщение необязательно
Telegram необязательно
@
Если укажете Telegram — мы ответим и там, в дополнение к Email.
WhatsApp необязательно
Формат: +код страны и номер (например, +380XXXXXXXXX).

Нажимая кнопку, вы соглашаетесь на обработку данных.