Guides 7 Min. Lesezeit

Health-Check-Endpoint bauen (und überwachen): So geht’s

Ein Health-Check-Endpoint sagt Monitoren und Load Balancern, ob Ihre App Anfragen bedienen kann. Was Sie prüfen sollten, wie er schnell und sicher bleibt, Code für Laravel, Express und Flask und wie Sie ihn überwachen.

Ein Health-Check-Endpoint ist eine URL, meist /health, die einem Monitor oder Load Balancer sagt, ob Ihre Anwendung Anfragen bedienen kann. Er führt ein paar schnelle Prüfungen gegen das aus, wovon die App abhängt, etwa Datenbank, Cache und freien Speicherplatz, und antwortet mit HTTP 200 und {„status“:“ok“}, wenn alles funktioniert, oder mit HTTP 503 und dem Namen der fehlgeschlagenen Prüfung, wenn nicht. Halten Sie ihn schnell, ressourcenschonend, ungecacht und frei von Geheimnissen, und richten Sie dann einen Uptime-Monitor darauf, der die Antwort validiert und nicht nur den Statuscode.

Dieser Leitfaden erklärt den Unterschied zwischen Liveness und Readiness, was Sie prüfen sollten, das Antwortformat, funktionierende Beispiele für PHP mit Laravel, Node mit Express und Python mit Flask und wie Sie den Endpoint überwachen, sobald er existiert.

Warum die Startseite kein Health Check ist

Die meisten Teams überwachen zuerst die Startseite. Das ist ein sinnvoller erster Schritt, aber die Startseite kommt oft aus einem CDN oder Seiten-Cache und antwortet deshalb weiter mit 200, während die Datenbank down ist und sich niemand einloggen oder bezahlen kann. Ein eigener Endpoint umgeht den Cache und spricht die Abhängigkeiten direkt an. Außerdem bekommen Sie eine vorhersehbare URL mit einer kleinen, stabilen Antwort, die sich leicht validieren lässt.

Liveness und Readiness

Container-Plattformen wie Kubernetes teilen den Zustand in zwei Fragen auf, und diese Trennung ist überall nützlich:

Liveness: Lebt der Prozess und hängt er nicht? Wenn nicht, starten Sie ihn neu. Ein Liveness-Check sollte weder die Datenbank noch andere Dienste testen. Fällt die Datenbank aus und jede App-Instanz besteht ihren Liveness-Check nicht mehr, startet die Plattform alle neu – das repariert die Datenbank nicht und verzögert die Wiederherstellung.

Readiness: Kann diese Instanz gerade echte Anfragen bedienen? Wenn nicht, schicken Sie ihr keinen Traffic mehr. Hierhin gehören die Prüfungen der Abhängigkeiten.

Ein gängiger Aufbau ist /livez oder /up für Liveness, das 200 liefert, solange die App startet, und /health oder /readyz für Readiness. Für externes Uptime-Monitoring ist der Readiness-Endpoint der interessante, denn er beantwortet die Frage, die Ihre Kunden interessiert: Funktioniert die App?

Was Sie prüfen sollten

Prüfen Sie die Abhängigkeiten, ohne die eine normale Anfrage scheitern würde, und nicht mehr:

Datenbank: Führen Sie SELECT 1 über denselben Connection-Pool aus, den die App nutzt. Das beweist, dass der Server erreichbar ist und Abfragen annimmt.

Cache oder Session-Store: Schreiben und lesen Sie einen kurzlebigen Schlüssel in Redis oder Memcached. Liegen die Sessions dort, hängt der Login davon ab.

Festplatte: Prüfen Sie den freien Speicherplatz auf dem Volume, auf das die App schreibt, etwa für Uploads, Logs oder Sessions. Lassen Sie die Prüfung fehlschlagen, wenn er unter eine Reserve fällt, zum Beispiel 10 Prozent.

Queue: Prüfen Sie, ob das Queue-Backend antwortet, und optional, ob der älteste wartende Job nicht älter als ein von Ihnen gewähltes Limit ist. Ein wachsender Rückstau bedeutet, dass die Worker stehen.

Vorsicht bei Drittanbieter-APIs. Ruft Ihr Endpoint bei jeder Prüfung einen Zahlungsanbieter auf und ist dieser langsam, schlägt Ihr Health Check fehl, obwohl Ihre eigene App in Ordnung ist – und ein Load Balancer nimmt womöglich jede Instanz aus der Rotation. Überwachen Sie Drittanbieter stattdessen mit eigenen Monitoren, damit ein Alarm zeigt, wessen Problem es ist. Das Drittanbieter-Monitoring von Uptimecheck verfolgt die Statusseiten von 31 Diensten wie Klarna, Swish, Shopify, Cloudflare und OpenAI oder jede auf Statuspage gehostete Seite.

Schnell und ressourcenschonend bleiben

Ein Health Check läuft jede Minute von jedem Monitor und Load Balancer aus, rund um die Uhr. Er darf nie selbst zu dem werden, was die App überlastet.

Geben Sie jeder Abhängigkeitsprüfung ein eigenes kurzes Timeout, zum Beispiel ein oder zwei Sekunden, damit ein hängender Dienst nicht den ganzen Endpoint blockiert.

Führen Sie Prüfungen parallel aus, wo Ihre Sprache das leicht macht.

Nutzen Sie triviale Abfragen. Zählen Sie nie Zeilen in einer großen Tabelle und erzeugen Sie keine Berichte.

Rufen viele Prüfer den Endpoint auf, cachen Sie das Ergebnis für ein paar Sekunden im Speicher.

Senden Sie Cache-Control: no-store und nehmen Sie den Pfad von Seiten-Caches und CDNs aus, damit Sie nie ein gecachtes „ok“ sehen.

Lassen Sie Sessions, Cookies und Authentifizierungs-Middleware weg, die der Endpoint nicht braucht.

Keine Geheimnisse preisgeben

Ein öffentlicher Health-Endpoint ist für jeden sichtbar, der /health errät. Geben Sie den Namen und Zustand jeder Prüfung zurück und sonst nichts. Keine Fehlermeldungen von Exceptions, Connection-Strings, Hostnamen, internen IP-Adressen, Softwareversionen oder Umgebungsvariablen. Protokollieren Sie den ausführlichen Fehler stattdessen auf dem Server. Wenn Sie eine detailliertere Diagnoseansicht möchten, legen Sie sie auf einen separaten Pfad hinter einer Authentifizierung oder beschränken Sie sie auf Ihr internes Netzwerk.

Antwortformat und Statuscodes

Halten Sie das JSON klein und stabil:

{
„status“: „ok“,
„checks“: {
„database“: „ok“,
„cache“: „ok“,
„disk“: „ok“,
„queue“: „ok“
}
}

Schlägt eine Prüfung fehl, setzen Sie ihren Wert auf „fail“, den Status auf oberster Ebene auf „fail“ und ändern Sie den HTTP-Statuscode:

200 OK, wenn jede erforderliche Prüfung besteht.

503 Service Unavailable, wenn eine erforderliche Prüfung fehlschlägt. Diesen Code erwarten Load Balancer und Monitore für „vorübergehend nicht verfügbar“.

Optional 200 mit „status“:“degraded“ für eine optionale Abhängigkeit, die ausgefallen ist, während der Kern weiter funktioniert. Legen Sie vorab fest, welche Prüfungen erforderlich sind.

Vermeiden Sie es, 200 mit „status“:“fail“ im Body zurückzugeben. Viele Tools lesen nur den Statuscode. Unter HTTP-Statuscodes im Monitoring erfahren Sie, wie die einzelnen Codes üblicherweise behandelt werden.

Beispiel: PHP und Laravel

Aktuelle Laravel-Versionen bringen eine einfache Route /up mit, die bestätigt, dass die App startet – ein guter Liveness-Check. Für Readiness fügen Sie eine Route hinzu, die die Abhängigkeiten prüft:

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‘);
});

Registrieren Sie sie außerhalb von Middleware-Gruppen, die Sessions starten, und setzen Sie in Ihrer Konfiguration ein kurzes Verbindungs-Timeout für die Datenbank.

Beispiel: Node und 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 });
});

Die Prüfungen laufen parallel, jede mit einem Limit von zwei Sekunden, sodass der Endpoint auch dann nach etwa zwei Sekunden antwortet, wenn eine Abhängigkeit hängt.

Beispiel: Python und 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“}

Ergänzen Sie auf dieselbe Weise eine Redis-Prüfung, wenn Sie Redis für Sessions oder eine Task-Queue nutzen.

Den Fehlerfall testen

Ein Health Check, der nie fehlgeschlagen ist, wurde nie getestet. Stoppen Sie in der Staging-Umgebung die Datenbank oder lassen Sie die App auf einen falschen Cache-Host zeigen und prüfen Sie, ob der Endpoint innerhalb Ihres Timeouts 503 liefert und die richtige Prüfung nennt. Prüfen Sie dann, dass die Antwort keinen Fehlertext enthält. Das dauert zehn Minuten und zeigt Ihnen, dass der Endpoint ehrlich ist, wenn es darauf ankommt.

Den Endpoint überwachen

Ein Endpoint, den niemand von außen prüft, ist nur die halbe Arbeit. Richten Sie einen HTTP-Monitor von außerhalb Ihres Netzwerks darauf, damit er auch DNS-, TLS-, Firewall- und Load-Balancer-Probleme erkennt:

Überwachen Sie https://lumenanalytics.io/health jede Minute mit GET.

Erwarten Sie Status 200 und validieren Sie, dass der Body „status“:“ok“ enthält. Eine Proxy-Fehlerseite, die zufällig 200 liefert, lässt den Check dann trotzdem fehlschlagen.

Senden Sie einen eigenen User-Agent-Header, damit sich Monitoring-Traffic leicht aus Analytics und Logs herausfiltern lässt.

Behalten Sie den Verlauf der Antwortzeiten im Blick. Ein Health Check, der von 40 ms auf 900 ms kriecht, ist ein frühes Warnsignal für eine angeschlagene Datenbank.

Leiten Sie den Alarm an die Personen weiter, die für den Dienst verantwortlich sind.

Das API-Monitoring von Uptimecheck unterstützt eigene Methoden und Header (auch Basic Auth oder ein Bearer-Token) und validiert den erwarteten Status, Keywords und JSON-Felder, sodass dieses Setup eine Minute dauert. Behalten Sie daneben einen regulären Uptime-Monitor für die Startseite und die wichtigste Conversion-Seite; die Checkliste fürs API-Monitoring behandelt die weiteren Endpoints, die sich zu überwachen lohnen.

Queue-Worker und geplante Tasks laufen oft außerhalb des Webprozesses, daher kann ein Health-Endpoint nicht sehen, ob sie stehen geblieben sind. Geben Sie ihnen stattdessen Heartbeats: Der Worker pingt alle paar Minuten eine URL an, und ein ausbleibender Ping löst den Alarm aus.

Checkliste für Health-Check-Endpoints

Trennen Sie Liveness (Prozess lebt) von Readiness (Abhängigkeiten funktionieren).

Prüfen Sie Datenbank, Cache, Festplatte und Queue, die die App zum Bedienen einer Anfrage braucht.

Geben Sie jeder Prüfung ein kurzes Timeout und halten Sie Abfragen trivial.

Liefern Sie 200, wenn alles gesund ist, und 503, wenn eine erforderliche Prüfung fehlschlägt.

Geben Sie nur Namen und Zustände der Prüfungen zurück. Keine Fehler, Versionen oder Hostnamen.

Deaktivieren Sie das Caching für den Pfad.

Überwachen Sie ihn jede Minute von außen, mit Validierung der Antwort.

Uptimecheck überwacht Health-Endpoints, APIs, Server und geplante Jobs in einem Konto. Starten Sie eine 14-tägige kostenlose Testphase, ohne Kreditkarte.

Fragen

Was sollte ein Health-Check-Endpoint zurückgeben?

Einen kleinen JSON-Body mit einem Gesamtstatus und dem Zustand jeder Prüfung, mit HTTP 200, wenn alles Erforderliche funktioniert, und HTTP 503, wenn eine erforderliche Prüfung fehlschlägt.

Sollte ein Health Check die Datenbank testen?

Der Readiness-Check schon, mit einer trivialen Abfrage wie SELECT 1 und einem kurzen Timeout. Ein Liveness-Check nicht, denn sonst würde ein Datenbankausfall jede App-Instanz neu starten.

Ist es sicher, einen Health-Endpoint öffentlich zu machen?

Ja, wenn er nur Namen und Zustände der Prüfungen zurückgibt. Halten Sie Fehlermeldungen, Versionen, Hostnamen und Verbindungsdetails aus der Antwort heraus und protokollieren Sie sie stattdessen auf dem Server.

Wie oft sollte ein Health-Check-Endpoint überwacht werden?

Bei Produktivdiensten jede Minute. Validieren Sie neben dem Statuscode auch, dass der Body den erwarteten Status enthält, damit eine gecachte Seite oder eine Proxy-Fehlerseite nicht als bestanden gilt.

Weiterlesen

Guides 7 Min. Lesezeit

Fehlalarme im Uptime-Monitoring reduzieren: So geht’s

Fehlalarme bringen Teams bei, das Monitoring zu ignorieren. So reduzieren Sie das Rauschen: jeden Fehler mit einem zweiten Check bestätigen, sinnvolle Timeouts setzen, die richtige URL prüfen und Alarme an die Leute leiten, die handeln können.

Lesen

Guides 5 Min. Lesezeit

API-Monitoring-Checkliste: Mehr prüfen als 200 OK

Eine API kann 200 zurückgeben und trotzdem kaputt sein. Eine praktische Checkliste für API-Monitoring: Methoden, Header, Request-Bodys, Authentifizierung, erwartete Antworten und Schwellenwerte für die Antwortzeit.

Lesen

Guides 4 Min. Lesezeit

Kosten eines Website-Ausfalls: So berechnen Sie Ihre

Was kostet eine Stunde offline wirklich? Eine einfache Formel für die direkten und versteckten Kosten von Ausfällen, Rechenbeispiele und was Uptime-Prozentwerte in Geld bedeuten.

Lesen

Downtime ist von gestern.

Richten Sie Ihren ersten Monitor in weniger als einer Minute ein – oder sehen Sie sich zuerst die Live-Demo an.

14 Tage kostenlos testen · Danach gratis für 5 Monitore · Keine Kreditkarte