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`.
- readiness: `period=5s, timeout=0.2–0.5s, failure=2`
- liveness: `period=10s, timeout=0.2–0.5s, failure=3`
- startup: `period=5s, failure=60` (до ~5 мин)
- readiness/liveness активируются после успеха startup
- 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»
- «Менеджмент секретов»