Проектирование health check эндпоинтов для веб-сервисов
Health check эндпоинт — выделенный URL, сообщающий о состоянии приложения. Основа автоматического мониторинг сайтов, маршрутизации балансировщика и оркестрации контейнеров. Правильный health check предотвращает ложные срабатывания и даёт actionable информацию.
Типы health check
Liveness Check
Отвечает: «Процесс приложения работает?» Минимальная проверка — при неудаче приложение нужно перезапустить.
GET /health/live → 200 OK
{"status": "alive"}
Проверяйте только сам процесс. Не проверяйте зависимости — сбой БД не должен вызывать перезапуск приложения.
Readiness Check
Отвечает: «Этот инстанс может обрабатывать трафик?» Проверяет зависимости. При неудаче — убрать из балансировщика, но не перезапускать.
GET /health/ready → 200 OK
{
"status": "ready",
"checks": {
"database": {"status": "up", "latency_ms": 3},
"redis": {"status": "up", "latency_ms": 1}
}
}
GET /health/ready → 503
{
"status": "not_ready",
"checks": {
"database": {"status": "down", "error": "Connection refused"},
"redis": {"status": "up"}
}
}
Startup Check
Отвечает: «Приложение завершило запуск?» Предотвращает трафик до завершения инициализации.
Что проверять
- БД:
SELECT 1 - Кеш: Redis/Memcached Ping
- Диск: достаточно места для логов и загрузок
- Память: алерт до OOM
- Внешние API документацию: критичные зависимости (осторожно — их нестабильность не должна ронять вас)
- Очереди: не растёт ли очередь задач?
- Сертификаты: предупреждение за дни до истечения SSL
Формат ответа
{
"status": "healthy",
"version": "2.4.1",
"uptime_seconds": 86432,
"checks": {
"mysql": {"status": "up", "latency_ms": 2},
"redis": {"status": "up", "latency_ms": 0.5},
"disk": {"status": "warning", "free_gb": 5.2}
}
}
HTTP-коды
200 OK— все проверки пройдены503 Service Unavailable— критические проверки не пройдены
Не используйте 500 — это неожиданная ошибка. 503 — «временно недоступен», правильная семантика.
Советы по реализации
Быстрота
Health check вызывается каждые 5-30 секунд. Ответ <1 секунды. Таймаут зависимостей — 2-3 секунды.
Устойчивость к нагрузке
Health check, падающий под нагрузкой, заставит балансировщик убрать инстанс — уменьшая ёмкость когда она нужна больше всего.
Кеширование проверок
Не запрашивайте БД при каждом вызове. Кешируйте результаты на 5-10 секунд.
Публичный vs внутренний
Публичный (/health): только код ответа. Внутренний (/health/detailed): полная диагностика. Защитите детальный эндпоинт.
Пример на PHP
$checks = [];
$healthy = true;
try {
$start = microtime(true);
$db = getDB();
$db->query('SELECT 1');
$checks['mysql'] = ['status' => 'up', 'latency_ms' => round((microtime(true) - $start) * 1000, 1)];
} catch (Exception $e) {
$checks['mysql'] = ['status' => 'down'];
$healthy = false;
}
try {
$start = microtime(true);
$redis = getRedis();
$redis->ping();
$checks['redis'] = ['status' => 'up', 'latency_ms' => round((microtime(true) - $start) * 1000, 1)];
} catch (Exception $e) {
$checks['redis'] = ['status' => 'down'];
$healthy = false;
}
http_response_code($healthy ? 200 : 503);
echo json_encode(['status' => $healthy ? 'healthy' : 'unhealthy', 'checks' => $checks]);
Заключение
Health check эндпоинты просты в создании, но критичны в реализации. Разделяйте liveness и readiness, держите проверки быстрыми, защищайте детальные эндпоинты и убедитесь, что они работают под нагрузкой.
Проверьте ваш сайт прямо сейчас
Проверить →