Endpoint health check to adres URL, zwykle /health, który mówi monitorowi lub load balancerowi, czy Twoja aplikacja może obsługiwać żądania. Wykonuje kilka szybkich testów zależności aplikacji, takich jak baza danych, cache i wolne miejsce na dysku, i odpowiada HTTP 200 z {„status”:”ok”}, gdy wszystko działa, albo HTTP 503 z nazwą nieudanego testu, gdy coś zawodzi. Niech będzie szybki, tani, bez cache’owania i bez sekretów, a potem skieruj na niego monitor dostępności, który sprawdza treść odpowiedzi, a nie tylko kod statusu.
Ten poradnik wyjaśnia różnicę między liveness a readiness, co sprawdzać, jaki format odpowiedzi przyjąć, pokazuje działające przykłady dla PHP z Laravelem, Node z Expressem i Pythona z Flaskiem oraz opisuje, jak monitorować gotowy endpoint.
Dlaczego strona główna to nie health check
Większość zespołów zaczyna od monitorowania strony głównej. To rozsądny pierwszy krok, ale strona główna często jest serwowana z CDN lub cache stron, więc odpowiada 200 nawet wtedy, gdy baza danych leży i nikt nie może się zalogować ani dokończyć zakupu. Dedykowany endpoint omija cache i bezpośrednio sprawdza zależności. Daje też jeden przewidywalny adres URL z małą, stabilną odpowiedzią, którą łatwo zweryfikować.
Liveness a readiness
Platformy kontenerowe, takie jak Kubernetes, dzielą kondycję aplikacji na dwa pytania – i ten podział przydaje się wszędzie:
Liveness: czy proces żyje i nie utknął? Jeśli nie, zrestartuj go. Test liveness nie powinien sprawdzać bazy danych ani innych usług. Jeśli baza padnie, a każda instancja aplikacji nie przejdzie testu liveness, platforma zrestartuje je wszystkie – to nie naprawi bazy, a tylko spowolni powrót do działania.
Readiness: czy ta instancja może teraz obsługiwać prawdziwe żądania? Jeśli nie, przestań kierować do niej ruch. To tutaj należą testy zależności.
Typowy układ to /livez lub /up dla liveness, zwracający 200, dopóki aplikacja się uruchamia, oraz /health lub /readyz dla readiness. Przy zewnętrznym monitorowaniu dostępności ciekawszy jest endpoint readiness, bo odpowiada na pytanie, które obchodzi Twoich klientów: czy aplikacja działa?
Co sprawdzać
Sprawdzaj zależności, bez których zwykłe żądanie by się nie powiodło – i nic ponadto:
Baza danych: wykonaj SELECT 1 na tej samej puli połączeń, z której korzysta aplikacja. To dowodzi, że serwer jest osiągalny i przyjmuje zapytania.
Cache lub magazyn sesji: zapisz i odczytaj krótkotrwały klucz w Redisie lub Memcached. Jeśli przechowujesz tam sesje, logowanie od tego zależy.
Dysk: sprawdź wolne miejsce na wolumenie, na który aplikacja zapisuje przesłane pliki, logi lub sesje. Zgłaszaj błąd, gdy spadnie poniżej marginesu, na przykład 10 procent.
Kolejka: sprawdź, czy backend kolejki odpowiada, i opcjonalnie, czy najstarsze oczekujące zadanie nie jest starsze niż wybrany przez Ciebie limit. Rosnąca zaległość oznacza, że workery przestały działać.
Uważaj na zewnętrzne API. Jeśli Twój endpoint przy każdym teście odpytuje operatora płatności, a ten działa wolno, health check zawiedzie, choć Twoja aplikacja ma się dobrze – a load balancer może wyłączyć z ruchu wszystkie instancje. Zamiast tego monitoruj usługi zewnętrzne osobnymi monitorami, żeby alert od razu mówił, czyj to problem. Monitorowanie usług zewnętrznych w Uptimecheck śledzi strony statusu 31 usług, takich jak Klarna, Swish, Shopify, Cloudflare i OpenAI, albo dowolną stronę hostowaną w Statuspage.
Niech będzie szybki i tani
Health check jest wywoływany co minutę przez każdy monitor i load balancer, przez całą dobę. Nigdy nie może stać się tym, co przeciąża aplikację.
Daj każdemu testowi zależności własny krótki timeout, na przykład sekundę lub dwie, żeby jedna zawieszona usługa nie zawiesiła całego endpointu.
Uruchamiaj testy równolegle tam, gdzie Twój język to ułatwia.
Używaj trywialnych zapytań. Nigdy nie licz wierszy w dużej tabeli ani nie generuj raportu.
Jeśli endpoint odpytuje wiele narzędzi, przechowuj wynik w pamięci przez kilka sekund.
Wysyłaj Cache-Control: no-store i wyłącz tę ścieżkę z cache stron i CDN, żeby nigdy nie zobaczyć „ok” z pamięci podręcznej.
Pomiń sesje, ciasteczka i middleware uwierzytelniania, których endpoint nie potrzebuje.
Nie ujawniaj sekretów
Publiczny endpoint health check zobaczy każdy, kto zgadnie /health. Zwracaj nazwę i stan każdego testu – i nic więcej. Nie umieszczaj w odpowiedzi komunikatów wyjątków, connection stringów, nazw hostów, wewnętrznych adresów IP, wersji oprogramowania ani zmiennych środowiskowych. Szczegółowy błąd zapisuj w logach na serwerze. Jeśli chcesz bogatszego widoku diagnostycznego, umieść go pod osobną ścieżką za uwierzytelnianiem albo ogranicz dostęp do sieci wewnętrznej.
Format odpowiedzi i kody statusu
Niech JSON będzie mały i stabilny:
{
„status”: „ok”,
„checks”: {
„database”: „ok”,
„cache”: „ok”,
„disk”: „ok”,
„queue”: „ok”
}
}
Gdy test zawiedzie, ustaw jego wartość na „fail”, ustaw status najwyższego poziomu na „fail” i zmień kod statusu HTTP:
200 OK, gdy przechodzą wszystkie wymagane testy.
503 Service Unavailable, gdy wymagany test zawiedzie. Tego kodu load balancery i monitory oczekują w sytuacji „chwilowo nie mogę obsługiwać żądań”.
Opcjonalnie 200 z „status”:”degraded”, gdy nie działa opcjonalna zależność, a rdzeń aplikacji wciąż działa. Z góry zdecyduj, które testy są wymagane.
Unikaj zwracania 200 z „status”:”fail” w treści. Wiele narzędzi odczytuje tylko kod statusu. Jak zwykle traktowany jest każdy kod, opisuje artykuł Kody statusu HTTP w monitorowaniu.
Przykład: PHP i Laravel
Nowsze wersje Laravela mają wbudowaną prostą trasę /up, która potwierdza, że aplikacja się uruchamia – to dobry test liveness. Dla readiness dodaj trasę, która sprawdza zależności:
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Route;
Route::get(’/health’, function () {
$checks = [];
try {
DB::select(’SELECT 1′);
$checks[’database’] = 'ok’;
} catch (\Throwable $e) {
report($e);
$checks[’database’] = 'fail’;
}
try {
Cache::put(’health-check’, 'ok’, 10);
$checks[’cache’] = Cache::get(’health-check’) === 'ok’ ? 'ok’ : 'fail’;
} catch (\Throwable $e) {
report($e);
$checks[’cache’] = 'fail’;
}
$path = storage_path();
$checks[’disk’] = disk_free_space($path) / disk_total_space($path) > 0.10 ? 'ok’ : 'fail’;
$healthy = ! in_array(’fail’, $checks, true);
return response()
->json([’status’ => $healthy ? 'ok’ : 'fail’, 'checks’ => $checks], $healthy ? 200 : 503)
->header(’Cache-Control’, 'no-store’);
});
Zarejestruj ją poza grupami middleware, które uruchamiają sesje, i ustaw w konfiguracji krótki timeout połączenia z bazą danych.
Przykład: Node i Express
const withTimeout = (promise, ms) =>
Promise.race([
promise,
new Promise((_, reject) => setTimeout(() => reject(new Error(’timeout’)), ms)),
]);
const check = (fn) => withTimeout(fn(), 2000).then(() => 'ok’, () => 'fail’);
app.get(’/health’, async (req, res) => {
const [database, cache] = await Promise.all([
check(() => pool.query(’SELECT 1′)),
check(() => redis.ping()),
]);
const checks = { database, cache };
const healthy = Object.values(checks).every((v) => v === 'ok’);
res
.set(’Cache-Control’, 'no-store’)
.status(healthy ? 200 : 503)
.json({ status: healthy ? 'ok’ : 'fail’, checks });
});
Testy działają równolegle, każdy z limitem dwóch sekund, więc endpoint odpowiada w ciągu około dwóch sekund nawet wtedy, gdy któraś zależność się zawiesi.
Przykład: Python i Flask
import shutil
from flask import jsonify
from sqlalchemy import text
@app.get(„/health”)
def health():
checks = {}
try:
db.session.execute(text(„SELECT 1”))
checks[„database”] = „ok”
except Exception:
app.logger.exception(„health: database”)
checks[„database”] = „fail”
usage = shutil.disk_usage(„/”)
checks[„disk”] = „ok” if usage.free / usage.total > 0.10 else „fail”
healthy = all(value == „ok” for value in checks.values())
body = {„status”: „ok” if healthy else „fail”, „checks”: checks}
return jsonify(body), 200 if healthy else 503, {„Cache-Control”: „no-store”}
W ten sam sposób dodaj test Redisa, jeśli używasz go do sesji lub kolejki zadań.
Przetestuj scenariusz awarii
Health check, który nigdy nie zawiódł, nigdy nie został przetestowany. Na środowisku stagingowym zatrzymaj bazę danych albo skieruj aplikację na błędny host cache i potwierdź, że endpoint zwraca 503 w ramach Twojego timeoutu i wskazuje właściwy test. Następnie upewnij się, że odpowiedź nie zawiera treści błędu. Zajmuje to dziesięć minut i daje pewność, że endpoint powie prawdę wtedy, gdy będzie to ważne.
Monitorowanie endpointu
Endpoint, którego nikt nie sprawdza z zewnątrz, to tylko połowa pracy. Skieruj na niego monitor HTTP spoza Twojej sieci, żeby wychwytywał też problemy z DNS, TLS, firewallem i load balancerem:
Monitoruj https://lumenanalytics.io/health metodą GET co minutę.
Oczekuj statusu 200 i sprawdzaj, czy treść zawiera „status”:”ok”. Wtedy strona błędu proxy, która przypadkiem zwraca 200, i tak nie przejdzie testu.
Wysyłaj własny nagłówek User-Agent, żeby ruch z monitoringu łatwo było odfiltrować z analityki i logów.
Obserwuj historię czasu odpowiedzi. Health check, który powoli rośnie z 40 ms do 900 ms, to wczesne ostrzeżenie, że baza danych nie nadąża.
Kieruj alert do osób odpowiedzialnych za usługę.
Monitorowanie API w Uptimecheck obsługuje własne metody i nagłówki (w tym basic auth lub token bearer) oraz sprawdza oczekiwany status, słowa kluczowe i pola JSON, więc taka konfiguracja zajmuje minutę. Obok utrzymuj zwykły monitor dostępności strony głównej i najważniejszej strony konwersji; lista kontrolna monitorowania API opisuje inne endpointy, które warto obserwować.
Workery kolejek i zadania cykliczne często działają poza procesem webowym, więc endpoint health check nie widzi, czy przestały działać. Zamiast tego daj im heartbeaty: worker co kilka minut wywołuje adres URL, a brak takiego sygnału uruchamia alert.
Lista kontrolna endpointu health check
Oddziel liveness (proces żyje) od readiness (zależności działają).
Sprawdzaj bazę danych, cache, dysk i kolejkę, których aplikacja potrzebuje do obsługi żądania.
Daj każdemu testowi krótki timeout i używaj trywialnych zapytań.
Zwracaj 200, gdy wszystko działa, i 503, gdy wymagany test zawiedzie.
Zwracaj tylko nazwy i stany testów. Żadnych błędów, wersji ani nazw hostów.
Wyłącz cache’owanie dla tej ścieżki.
Monitoruj endpoint co minutę z zewnątrz, z weryfikacją odpowiedzi.
Uptimecheck monitoruje endpointy health check, API, serwery i zadania cykliczne w jednym koncie. Rozpocznij 14-dniowy darmowy okres próbny, bez karty kredytowej.