Zum Inhalt springen
DSGVO-konform. Gehostet in DE.
14 Tage kostenlos testen →
Liveness, Readiness, StartupHarte und weiche AbhängigkeitenStatuscode statt Rumpf
Monitoring 14 Min. Lesezeit 8. Sept. 2026

Health-Check-Endpunkt bauen: flach prüfen reicht nicht

Warum ein 200 vom Health-Endpunkt nichts über die Datenbank sagt - und wie Liveness, Readiness und Startup mit Zeitbudget und Statuscodes sauber getrennt werden.

X

XICTRAQ

XICTRAQ

Health-CheckAPI-MonitoringAbhängigkeiten
10 s
Prüftakt im Standard (Kubernetes-Dokumentation)
1 s
Frist je Probe im Standard (Kubernetes-Dokumentation)
50 %
Schwelle der Notbremse im Vermittler (Envoy)
Fünf Schichten, ein Endpunkt - flach prüfen oder tiefStatuspunkt, Antwortzeit und Prüftiefe je Schicht des AufrufwegsSchichtStatusAntwortzeit (schematisch)PrüftiefeWebservernimmt HTTP anpassflachAnwendungeigener ProzesspassflachDatenbankharte AbhängigkeitfailtiefWarteschlangeweiche AbhängigkeitwarntiefExterner Dienstweiche AbhängigkeitwarntiefStandardwerte der prüfenden SchichtKubernetes-Dokumentation10 sPrüftakt je Instanz1 sFrist je Aufruf3Fehlschläge bis Neustart
Ein Health-Check-Endpunkt ist die kürzeste Antwort auf die teuerste Frage im Betrieb: Läuft der Dienst noch, und wenn ja, wie weit? Die meisten Endpunkte beantworten davon nur die erste Hälfte. Sie liefern ein 200, sobald der Prozess HTTP annimmt, und schweigen zu der Datenbank, die seit vier Minuten keine Verbindung mehr herausgibt. Die Folgen sind konkret: Der Lastverteiler hält ein totes Ziel in der Rotation, die Überwachung meldet Grün, und die Störung fällt zuerst dem Kunden auf. Wer den Endpunkt umgekehrt zu tief prüft, baut sich das gespiegelte Problem - ein Aussetzer in einem fremden System reißt alle Instanzen gleichzeitig aus dem Verkehr. Der Grat dazwischen verläuft entlang von Standardwerten, die kaum jemand liest. Wer nichts einstellt, lässt die Container-Plattform den Endpunkt alle zehn Sekunden abfragen (Kubernetes-Dokumentation), mit einer Frist von genau einer Sekunde je Aufruf (Kubernetes-Dokumentation). Beides entscheidet über die Brauchbarkeit des Endpunkts, lange bevor die erste Zeile Prüfcode geschrieben ist.

Was ein flacher Health-Check tatsächlich beweist

Der flache Check ist schnell erzählt: Der Webserver nimmt die Anfrage an, das Anwendungsgerüst findet die Route, ein Handler gibt eine feste Antwort zurück. Damit ist genau eine Sache belegt - der Prozess lebt und beantwortet HTTP. Für die Frage nach einem Neustart ist das die richtige Auskunft. Ein Neustart repariert hängende Threads, verlorene Dateizeiger und Speicherlecks im eigenen Prozess. Er repariert nichts, was außerhalb dieses Prozesses kaputt ist. Genau deshalb darf der flache Check auch nichts anderes messen: Jede zusätzliche Abhängigkeit in dieser Prüfung macht aus einer fremden Störung einen eigenen Neustart.

Das Problem beginnt dort, wo dieselbe Antwort für eine andere Frage benutzt wird. Ein Lastverteiler fragt nicht, ob der Prozess lebt, sondern ob er diesem Ziel Kundenverkehr schicken darf. Ein Prozess kann laufen und trotzdem jede fachliche Anfrage mit einem Serverfehler beantworten, weil der Verbindungsvorrat zur Datenbank leer ist. Wer beide Fragen mit demselben Endpunkt beantwortet, hat sich unbeabsichtigt für eine der beiden Antworten entschieden. Welche Rolle der Takt dabei spielt, zeigt der Beitrag zur Wahl des Prüfintervalls und der daraus folgenden Erkennungszeit.

  • Erschöpfter Verbindungsvorrat: Die Datenbank antwortet, aber jede neue Anfrage wartet auf eine freie Verbindung und läuft in die Zeitüberschreitung.
  • Halb gelaufene Migration: Die Auslieferung hat Tabellen umbenannt, der Prozess läuft, die Abfragen greifen ins Leere.
  • Kalter Zwischenspeicher: Nach einem Neustart schlägt jede Anfrage bis auf die Platte durch, die Antwortzeit vervielfacht sich.
  • Verstopfte Warteschlange: Aufträge werden angenommen, aber nicht abgearbeitet - sichtbar erst Stunden später.
  • Abgelaufenes Zertifikat der Gegenstelle: Die eigene Anwendung ist gesund, der Aufruf der fremden Schnittstelle scheitert an der Kette.

Wie viel Zeit ein Endpunkt überhaupt hat, lässt sich an der Grundgesamtheit des offenen Webs ablesen. Nur 44 Prozent der mobilen Websites erreichen eine gute Serverantwortzeit, auf dem Schreibtischrechner sind es 55 Prozent (Web Almanac); die Schwelle für gut liegt bei 0,8 Sekunden, ab 1,8 Sekunden gilt sie als schlecht (Web Almanac). Ein Health-Endpunkt gehört deutlich unter diese Schwelle, denn er läuft nicht einmalig, sondern dauerhaft. Wie sich solche Zeiten sauber messen lassen, beschreibt der Beitrag zu Antwortzeit-Perzentilen und den Grenzen des Mittelwerts.

Liveness, Readiness und Startup: drei Fragen, drei Antworten

Die Trennung der Probenarten ist keine Geschmacksfrage, sondern eine Folge davon, was das System mit der Antwort anstellt. Die Liveness-Probe beantwortet: Soll dieser Prozess neu gestartet werden? Die Readiness-Probe beantwortet: Soll dieses Ziel Verkehr bekommen? Die Startup-Probe beantwortet: Ist der Hochlauf abgeschlossen? Drei Fragen, drei Reaktionen, drei völlig unterschiedliche Anforderungen an die Prüfung.

Der teuerste Zusammenlegungsfehler ist eine Liveness-Probe, die die Datenbank mitprüft. Fällt die Datenbank aus, startet die Plattform reihum jeden Container neu. Der Neustart behebt nichts, kostet aber den warmen Zwischenspeicher, die offenen Verbindungen und den Hochlauf. Danach ist die Anwendung langsamer als vorher, fällt erneut durch die Probe und wird erneut neu gestartet. Die Readiness-Probe darf die Datenbank dagegen prüfen: Ihre Reaktion ist der Abzug aus der Rotation, und der ist umkehrbar, sobald die Abhängigkeit zurück ist.

ProbenartBeantwortetPrüft sinnvollerweiseReaktion bei Fehlschlag
LivenessIst der Prozess handlungsfähig?nur den eigenen Prozess, keine AbhängigkeitNeustart des Containers - grob und teuer
ReadinessDarf dieses Ziel Verkehr bekommen?harte Abhängigkeiten mit knappem ZeitbudgetAbzug aus der Rotation - umkehrbar
StartupIst der Hochlauf abgeschlossen?Migration, Vorwärmung, geladene Konfigurationweiteres Warten, danach Neustart

Die Standardwerte zeigen, wie unterschiedlich die drei gemeint sind. Erst nach drei aufeinanderfolgenden Fehlschlägen gilt ein Container als defekt (Kubernetes-Dokumentation) - zusammen mit dem Standardintervall vergehen bis zum Neustart rund 30 Sekunden. Die erste Probe läuft dagegen ohne Vorlauf, sofort nach dem Start des Containers (Kubernetes-Dokumentation); ohne Startup-Probe trifft sie eine Anwendung, die noch gar nicht bereit sein kann. Und für Liveness- und Startup-Proben ist ein einziger Erfolg zwingend genug (Kubernetes-Dokumentation): Die Rückkehr in den gesunden Zustand lässt sich nicht entprellen, das Zurückschwingen also nicht dämpfen.

Der teuerste Fehler steht in drei Zeilen Konfiguration

Eine Liveness-Probe, die eine Datenbankabfrage ausführt, verwandelt jede Störung im Datenbestand in eine flottenweite Neustartschleife. Die Regel dagegen ist einfach und kostet nichts: In der Liveness-Probe steht kein Netzaufruf, keine Abfrage, kein Dateizugriff außerhalb des Prozesses. Wer eine Prüfung braucht, die anschlägt, wenn ein Hintergrundlauf ausbleibt, nimmt dafür keinen Health-Endpunkt, sondern einen Herzschlag mit Totmannschalter - der misst Ausbleiben statt Erreichbarkeit.

Die Standardwerte entscheiden mehr als der eigene Code

Ein Health-Endpunkt wird selten von einer einzigen Stelle abgefragt. Im typischen Aufbau fragen die Container-Plattform, der Lastverteiler, der vorgelagerte Webserver und die externe Überwachung denselben Pfad ab - jede Schicht mit eigenem Takt, eigener Frist und eigener Schwelle. Diese Werte stehen selten in der eigenen Konfiguration, sondern in den Standardeinstellungen der jeweiligen Dokumentation. Sie sind der eigentliche Vertrag, den der Endpunkt einhalten muss, und sie widersprechen sich zum Teil deutlich.

SchichtIntervall im StandardZeitgrenzeSchwelle bis krank
Container-Plattform (Kubernetes-Dokumentation)10 Sekunden1 Sekunde3 Fehlschläge
Lastverteiler (AWS)30 Sekunden5 Sekunden2 Fehlschläge
Lastverteiler (Microsoft)5 Sekunden über die Oberfläche, 15 Sekunden über Vorlagedas Kleinere aus Intervall und 30 Sekunden, also 5 beziehungsweise 15 Sekundenkein einheitlicher Wert
Webserver (nginx Plus, nur im kommerziellen Abo)5 Sekundenan die Weiterleitung gebunden1 Fehlschlag
Webserver (Apache HTTP Server)30 Sekunden, im Auslieferungszustand keine Prüfung (hcmethod None)an die Weiterleitung gebunden1 Fehlschlag (hcfails)

Am Lastverteiler fällt der Widerspruch am deutlichsten auf. Geprüft wird im Standard nur alle 30 Sekunden (AWS), und der Endpunkt hat fünf Sekunden Zeit zu antworten (AWS). Zwei fehlgeschlagene Prüfungen genügen, um ein Ziel aus dem Verkehr zu nehmen (AWS) - zurück in die Rotation kommt es aber erst nach fünf erfolgreichen Prüfungen in Folge (AWS). Ein Endpunkt, der gelegentlich in die Frist läuft, weil er eine fremde Schnittstelle mitprüft, verliert damit ein Ziel für Minuten, obwohl die Anwendung selbst nicht ausgefallen war. Wer Erreichbarkeit von außen misst, sieht diese Lücke sofort - das ist die Aufgabe der Uptime-Überwachung mit Antwortzeitmessung.

Ein zweiter Lastverteiler widerspricht sich sogar mit sich selbst. Über die grafische Oberfläche angelegt, prüft er alle fünf Sekunden (Microsoft); über Vorlage, Schnittstelle oder Kommandozeile angelegt, sind es 15 Sekunden (Microsoft). Dreifacher Takt bei identischer Absicht - das fällt erst im Störfall auf. Dazu kommt eine Frist von höchstens 30 Sekunden (Microsoft); wirksam ist aber das Kleinere aus Prüfintervall und diesen 30 Sekunden - im Standard also fünf beziehungsweise 15 Sekunden. Ein hängender Datenbankaufruf im Health-Endpunkt hält die Verbindung so lange offen und bindet einen Arbeiterthread.

Auf der Webserver-Ebene ist der Takt eng und die Entprellung schwach - dort, wo es überhaupt einen eigenen Takt gibt. Die aktive Prüfung health_check steckt im Modul ngx_http_upstream_hc_module und gehört zum kommerziellen Abo nginx Plus (nginx); dort wird im Standard alle fünf Sekunden geprüft (nginx), und eine einzige fehlgeschlagene Prüfung genügt, um einen Server aus der Gruppe zu werfen (nginx). Im freien nginx existiert diese aktive Prüfung nicht: Dort bleibt die passive Fehlerzählung über max_fails und fail_timeout, die nur die Fehler des echten Kundenverkehrs mitzählt - ein eigener Takt auf den Health-Endpunkt läuft dann gar nicht. Beim klassischen Webserver liegt das Prüfintervall bei 30 Sekunden, ein einziger Fehlschlag schaltet den Arbeiter ab (hcfails, Apache HTTP Server), und die dynamische Prüfung ist im Auslieferungszustand überhaupt nicht eingeschaltet (Apache HTTP Server). Alle diese Fälle führen zu demselben Schluss: Der Endpunkt muss so billig sein, dass er den engsten dieser Takte ohne Nachdenken verträgt.

Der Endpunkt ist kein Sonderfall, sondern Dauerlast

Bei einem Intervall von zehn Sekunden (Kubernetes-Dokumentation) läuft je Instanz sechsmal in der Minute ein Aufruf auf denselben Pfad, unabhängig vom Kundenverkehr. Multipliziert mit der Zahl der Instanzen und den vier Schichten, die alle denselben Pfad abfragen, wird aus der harmlosen Prüfung eine der am häufigsten aufgerufenen Adressen des ganzen Systems.

Der Statuscode ist das Signal - nicht der Rumpf

Ein verbreiteter Baufehler steckt nicht in der Prüflogik, sondern in der Antwort: Der Endpunkt sammelt sauber alle Teilzustände, schreibt sie in ein JSON-Dokument mit dem Wort fail und liefert das Ganze mit 200 aus. Für einen Menschen ist die Antwort eindeutig. Für jede Maschine davor ist sie ein Erfolg. Das etablierte Antwortformat regelt genau diesen Punkt: Ein bestandener Health-Check wird mit einem Code aus dem Bereich 2xx bis 3xx beantwortet (IETF), ein fehlgeschlagener mit 4xx oder 5xx (IETF). Ein 200 mit dem Wort fail im Rumpf ist formal falsch und wird von jeder vorgelagerten Schicht als gesund gelesen.

Interessant ist die dritte Stufe. Die Warnstufe wird bewusst mit einem Erfolgscode ausgeliefert (IETF) - der Statuscode allein trennt gesund also nicht von angeschlagen, dafür braucht es den Rumpf. Daraus folgt die Arbeitsteilung: Der Statuscode steuert die Maschine, der Rumpf den Menschen. Verbreitete Anwendungsgerüste bilden das bereits ab; für einen ausgefallenen Dienst liefern sie standardmäßig einen 503, während alles andere - auch ein unbekannter Zustand - als 200 herauskommt (Spring Boot). Wer eigene Zustände einführt, muss die Abbildung selbst pflegen, sonst fällt ein neuer Zustand still auf gesund zurück.

health-antwort.json
HTTP/1.1 503 Service Unavailable
Content-Type: application/health+json
Cache-Control: max-age=3600

{
  "status": "fail",
  "version": "1",
  "serviceId": "checkout-api",
  "description": "Bestellannahme",
  "checks": {
    "postgres:responseTime": [
      { "componentType": "datastore", "status": "fail",
        "observedValue": 812, "observedUnit": "ms",
        "time": "2026-09-08T09:14:02Z",
        "output": "pool exhausted, 0 of 20 connections free" }
    ],
    "queue:depth": [
      { "componentType": "system", "status": "warn",
        "observedValue": 14203, "observedUnit": "jobs",
        "time": "2026-09-08T09:14:02Z" }
    ],
    "pdf-service:connectivity": [
      { "componentType": "component", "status": "warn",
        "observedValue": "degraded", "time": "2026-09-08T09:13:47Z",
        "output": "weiche Abhängigkeit, Ausgabe verzögert sich" }
    ]
  }
}

Wie eng das Fenster für den Statuscode ist, hängt von der prüfenden Schicht ab, und die Bandbreite ist erheblich. Die Container-Plattform wertet jeden Code von 200 bis 399 als Erfolg (Kubernetes-Dokumentation) - eine Weiterleitung auf eine Anmeldeseite gilt damit als gesunder Dienst. Auf der Webserver-Ebene gilt in der aktiven Prüfung ebenfalls jeder Code aus 2xx und 3xx als bestanden, solange keine eigene Regel gesetzt ist (nginx Plus). Ein Lastverteiler kann dagegen so streng eingestellt sein, dass ausschließlich der Code 200 als gesund zählt: Ein 204 ohne Rumpf oder eine 302 auf die Statusseite ist dort bereits ein Ausfall (Microsoft). Und die Erfolgsliste lässt sich nur zwischen 200 und 499 konfigurieren (AWS) - ein 5xx ist dort nicht als gesund hinterlegbar. Welche Codes im Alltag tatsächlich auflaufen, zeigt der Beitrag zur Überwachung der Serverfehlerrate im 5xx-Bereich.

Wenn der tiefe Check den Ausfall erst erzeugt

Tiefe Prüfungen haben eine unangenehme Eigenschaft: Sie sind gleichzeitig Messgerät und Last. Jeder Aufruf des Endpunkts erzeugt eine Datenbankabfrage, eine Verbindung zur Warteschlange, einen Aufruf der fremden Schnittstelle. Steht das System unter Druck, kommt diese Last genau dann obendrauf, wenn am wenigsten Reserve da ist. Wiederholen mehrere Ebenen unabhängig voneinander je dreimal, wird aus einem einzigen Klick eine Lawine von 64 Anfragen an die Datenbank (Google SRE Book).

only allow 60 retries per minute in a process, and if the retry budget is exceeded, don't retry

— Site Reliability Engineering, Kapitel 22: Addressing Cascading Failures

Die Empfehlung dahinter lautet, Wiederholungen zu deckeln: höchstens 60 Wiederholungen je Minute und Prozess, danach wird nicht mehr wiederholt (Google SRE Book). Fällt mehr als die Hälfte der Instanzen durch den Health-Check, verwirft ein verbreiteter Vermittler das Ergebnis und schickt wieder an alle - der Standardwert dieser Notbremse liegt bei 50 Prozent (Envoy). Ein zu strenger Check schaltet sich damit selbst ab, und zwar lautlos: Die Oberfläche zeigt weiter Instanzen als krank an, während der Verkehr längst wieder überall hinläuft. Wie man solche Zustandssprünge von echten Ausfällen unterscheidet, beschreibt der Beitrag zum Zähmen flatternder Alarme über mehrere Standorte.

Steckt ein Dienst bereits in der Neustartschleife, empfiehlt dasselbe Handbuch, zunächst nur ein Prozent des Verkehrs durchzulassen (Google SRE Book) - erst dann kann sich ein Zwischenspeicher füllen und ein Verbindungsvorrat aufbauen. Ein Health-Endpunkt, der bei jeder Prüfung volle Tiefe misst, verhindert genau diese Erholung: Er meldet krank, bis das System warm ist, und lässt es nicht warm werden, weil es keinen Verkehr bekommt. Warum fremde Abhängigkeiten dabei besondere Aufmerksamkeit brauchen, zeigt der Beitrag zu Cloud-Ausfällen und der Überwachung fremder Abhängigkeiten.

Harte und weiche Abhängigkeiten trennen

Die Trennung, die den Unterschied macht, ist nicht technisch, sondern fachlich: Ohne welche Abhängigkeit kann dieser Dienst seinen Zweck nicht erfüllen? Für eine Bestellannahme ist die Datenbank hart - ohne sie gibt es keine Bestellung. Der Dienst, der die Rechnung als PDF erzeugt, ist weich: Die Bestellung wird angenommen, die Ausgabe wandert in die Warteschlange. Sie ändert sich mit dem fachlichen Zuschnitt, und sie ist der einzige belastbare Grund, warum ein Teilzustand die Readiness kippen darf oder eben nicht.

Harte Abhängigkeit

Ohne sie ist der Zweck des Dienstes nicht erfüllbar. Sie gehört in die Readiness-Prüfung, mit knappem Zeitbudget und billiger Abfrage: eine Verbindung aus dem Vorrat, eine Anfrage ohne Tabellenzugriff.

Weiche Abhängigkeit

Ihr Ausfall verzögert oder verschlechtert, verhindert aber nicht. Sie gehört in den Rumpf der Antwort als Warnstufe, nicht in den Statuscode.

Fremde Frist

Bei jedem Aufruf über das Netz gilt die Frist der Gegenstelle, nicht die eigene. Ein abgelaufenes oder unvollständig ausgeliefertes Zertifikat kippt den Aufruf, ohne dass die Anwendung etwas davon merkt - Hintergrund dazu im Beitrag zur unvollständigen Zertifikatskette.

Eigene Reserve

Jede Prüfung braucht eine Antwort für den Fall, dass die Abhängigkeit nicht antwortet. Ohne definierten Rückfall wird aus einer offenen Verbindung ein hängender Thread - und aus mehreren ein Prozess, der auch die flache Prüfung nicht mehr bedient.

Diese Trennung hat einen messbaren Preis, wenn sie fehlt. Ein Verfügbarkeitsziel von 99,9 Prozent lässt 43,2 Minuten Ausfall im Monat zu (Google SRE Book). Jeder unnötige Abzug aus der Rotation, ausgelöst von einer weichen Abhängigkeit, geht aus demselben Budget. Wie sich das Budget kontrolliert verbrauchen lässt, statt es unbemerkt aufzuzehren, beschreibt der Beitrag zu Fehlerbudget und Verbrauchsrate als Alarmgrundlage.

Zeitbudget, Zwischenspeicher und ein eigener Takt

Ein tiefer Check ohne Zeitbudget ist kein Check, sondern eine Wette. Die engste Grenze im Aufbau gibt den Rahmen vor: Die Container-Plattform räumt einer Probe im Standard genau eine Sekunde ein (Kubernetes-Dokumentation), der Lastverteiler fünf (AWS). Ein brauchbarer Zuschnitt gibt jeder Teilprüfung eine eigene, deutlich kleinere Frist, führt sie nebenläufig aus und bricht die Gesamtprüfung ab, sobald das Budget aufgebraucht ist. Eine Teilprüfung, die in ihre Frist läuft, liefert dann fail für diesen Teil - und nicht eine Antwort, die gar nicht mehr kommt.

Der zweite Hebel ist der Takt. Die tiefe Prüfung muss nicht bei jedem Aufruf laufen. Ein Hintergrundlauf misst die Abhängigkeiten in eigenem Rhythmus und legt das Ergebnis samt Zeitstempel ab; der Endpunkt liest nur noch diesen Stand und antwortet in Mikrosekunden. Das Antwortformat sieht diese Entkopplung ausdrücklich vor und empfiehlt eine Frischedauer auf der Health-Antwort, damit Aufrufer den Endpunkt nicht ungebremst abfragen (IETF).

$ curl -s -o /dev/null -w '%{http_code} %{time_total}s\n' https://api.example/health/live
200 0.004s
$ curl -s -o /dev/null -w '%{http_code} %{time_total}s\n' https://api.example/health/ready
503 0.212s
$ curl -s https://api.example/health/ready | jq -r '.checks | to_entries[] | "\(.key)\t\(.value[0].status)"'
postgres:responseTime fail queue:depth warn pdf-service:connectivity warn
$ curl -sI https://api.example/health/ready | grep -i '^cache-control'
cache-control: no-store

Die letzte Zeile ist der eigentliche Befund dieser Messreihe: Der flache Pfad antwortet in vier Millisekunden, der tiefe in gut zweihundert - und die Antwort trägt keine Frischedauer, wird also von jedem Aufrufer in vollem Takt neu erzeugt. Genau solche Abweichungen zwischen zwei Pfaden desselben Dienstes lassen sich von außen laufend gegenprüfen, wenn beide Endpunkte als eigene Prüfungen im API-Monitoring liegen, mit eigenen Erwartungswerten für Code, Laufzeit und Inhalt.

Was in die Antwort gehört und was nicht

Ein Health-Endpunkt ist eine Betriebsschnittstelle, keine Systemauskunft. Alles, was ein Angreifer für die Zuordnung von Angriffswegen brauchen kann, gehört nicht hinein: Versionen, interne Adressen, Verbindungszeichenfolgen, Stapelspuren. Die Trennung ist einfach zu ziehen, wenn der Endpunkt zwei Ausbaustufen hat - eine öffentliche, die nur den Gesamtzustand und einen Zeitstempel trägt, und eine interne, die im Netz nicht erreichbar ist und die Teilzustände ausweist.

proben.yaml
livenessProbe:
  httpGet:
    path: /health/live      # nur der eigene Prozess, keine Netzaufrufe
    port: 8080
  periodSeconds: 10         # Standardwert, hier bewusst bestätigt
  timeoutSeconds: 1         # Standardwert - der Pfad muss darunter bleiben
  failureThreshold: 3

readinessProbe:
  httpGet:
    path: /health/ready     # harte Abhängigkeiten, aus dem Hintergrundlauf gelesen
    port: 8080
  periodSeconds: 5
  timeoutSeconds: 2
  failureThreshold: 2
  successThreshold: 2       # nur hier erlaubt: Entprellung beim Zurückschwingen

startupProbe:
  httpGet:
    path: /health/started   # Migration durch, Konfiguration geladen, Vorwärmung fertig
    port: 8080
  periodSeconds: 5
  failureThreshold: 60      # 5 Minuten Hochlauf, danach Neustart
  • Gesamtzustand als Statuscode: eine Stufe, drei Werte - bestanden, angeschlagen, ausgefallen -, sauber auf die Codebereiche abgebildet.
  • Zeitstempel je Teilprüfung: sagt, wie alt die Aussage ist, und entlarvt einen eingefrorenen Hintergrundlauf.
  • Kennzeichnung hart oder weich: macht im Rumpf sichtbar, warum ein Teilzustand den Gesamtzustand kippt oder eben nicht.
  • Keine Geheimnisse und keine Versionen: weder Zugangsdaten noch Bibliotheksstände, weder interne Namen noch Stapelspuren.

Damit die Antwort auch dann noch stimmt, wenn sich die Anwendung ändert, braucht sie eine Gegenprüfung von außen. Erwartungswerte auf Statuscode, Laufzeit und einzelne Felder im Rumpf halten fest, wie eine gesunde Antwort aussieht - und schlagen an, wenn ein Feld verschwindet oder ein Zustand still auf gesund zurückfällt. Wie sich solche Erwartungswerte sinnvoll schneiden lassen, beschreibt der Beitrag zu Zusicherungen und Schwellenwerten im API-Monitoring.

Von außen prüfen: der Blick des Aufrufers

Jede Prüfung aus dem eigenen Netz hat denselben blinden Fleck: Sie misst nicht den Weg, den der Kunde nimmt. Der Endpunkt kann innen sauber antworten, während davor eine Weiterleitung, eine Firewall oder eine abgelaufene Zertifikatskette die Antwort verändert. Deshalb gehört zu jedem Health-Endpunkt eine zweite Messung von außen, aus einem Netz, das nichts mit dem eigenen zu tun hat. Erst der Vergleich beider Messungen trennt zuverlässig zwischen einem Anwendungsfehler und einem Zustellungsfehler.

Die zweite Frage ist, was mit dem Befund passiert. Nützlich wird er erst, wenn Zustandswechsel gebündelt und nach Schwere getrennt zugestellt werden - eine ausgefallene harte Abhängigkeit weckt jemanden, eine warnende weiche wandert in den Tagesbericht. Diese Trennung ist der eigentliche Zweck der Statusstufen im Rumpf; sie zahlt erst dann, wenn die Alarmzustellung über getrennte Kanäle sie auch abbildet.

Für Kunden und Kollegen zählt am Ende nicht die Prüfung, sondern die Auskunft. Ein Zustandswechsel, der aus geprüften Werten in eine Statusseite mit Berichtsfunktion läuft, erspart im Störfall die Hälfte der Rückfragen - und macht im Nachgang nachvollziehbar, wann welcher Teilzustand gekippt ist.

Health-Checks als Betriebsentscheidung, nicht als Pflichtübung

Ein Health-Endpunkt ist kein Nebenprodukt, sondern eine Schnittstelle mit Vertragscharakter: Er sagt vier Schichten gleichzeitig, was sie mit einem Prozess anstellen sollen. Die drei Entscheidungen, die dabei zählen, sind schnell benannt - welche Abhängigkeit hart ist, wie viel Zeit die Prüfung bekommt und wie der Zustand auf Statuscodes abgebildet wird. Dass alte Komponenten dabei eigene Fallstricke mitbringen, zeigt der Beitrag zu Komponenten ohne Updates im Web-Stack.

Der Aufwand für den Umbau ist überschaubar, der Ertrag nicht: Getrennte Pfade, ein Hintergrundlauf mit Zeitstempel und drei sauber gesetzte Standardwerte verhindern die beiden teuersten Fehlerbilder - das tote Ziel in der Rotation und die flottenweite Neustartschleife. Wie viel Überwachung dafür nötig ist, hängt vom Zuschnitt ab; die Übersicht der Tarife und ihres Leistungsumfangs macht den Unterschied zwischen einer einzelnen Prüfung und einer Abdeckung über alle Endpunkte greifbar.

  1. Drei Pfade anlegen: /health/live ohne Abhängigkeiten, /health/ready mit harten Abhängigkeiten, /health/started für den Hochlauf.
  2. Je Abhängigkeit festhalten, ob sie hart oder weich ist - schriftlich.
  3. Zeitbudget je Teilprüfung setzen und die Summe unter die engste Frist der prüfenden Schicht legen.
  4. Zustände auf Statuscodes abbilden und die Abbildung mit einer Prüfung von außen absichern.
  5. Tiefe Prüfung in einen Hintergrundlauf verlegen und das Ergebnis mit Zeitstempel ausliefern.
  6. Beide Pfade extern überwachen, mit getrennten Schwellen und getrennten Zustellwegen.
Quellen und Studien

Dieser Beitrag stützt sich auf die Standardwerte und Festlegungen der jeweiligen Primärquellen: Kubernetes-Dokumentation (Liveness, Readiness, and Startup Probes), IETF-Entwurf Health Check Response Format for HTTP APIs, AWS-Dokumentation zu Health Checks für Application-Load-Balancer-Zielgruppen, Microsoft-Dokumentation zu Health Probes des Azure Load Balancer, nginx-Dokumentation zum Modul ngx_http_upstream_hc_module, Apache HTTP Server zum Modul mod_proxy_hcheck, Envoy-Dokumentation zum Panic Threshold, Google SRE Book (Kapitel 22, Addressing Cascading Failures, sowie Anhang A, Availability Table), Web Almanac 2025 (Kapitel Performance) und Spring-Boot-Referenz zu den Actuator-Endpunkten. Alle Werte sind Standardeinstellungen der jeweiligen Dokumentation und wurden am 08.09.2026 an der Quelle nachgelesen.

Reicht ein einziger Health-Endpunkt für alles?
In der Regel nicht. Die Container-Plattform startet bei einer fehlgeschlagenen Liveness-Probe den Prozess neu, der Lastverteiler zieht bei einer fehlgeschlagenen Prüfung nur Verkehr ab. Wer beide Fragen mit demselben Pfad beantwortet, bekommt Neustarts für Störungen, die durch einen Neustart nicht behoben werden. Üblich sind drei Pfade: einer ohne Abhängigkeiten für Liveness, einer mit harten Abhängigkeiten für Readiness und einer für den Hochlauf.
Warum soll ein fehlgeschlagener Check mit 503 antworten und nicht mit 200?
Weil die vorgelagerten Schichten den Statuscode auswerten und nicht den Rumpf. Das Antwortformat für Health-Checks legt fest, dass für den Status pass ein Code aus 2xx bis 3xx und für fail ein Code aus 4xx bis 5xx zu verwenden ist (IETF). Verbreitete Anwendungsgerüste bilden einen ausgefallenen Dienst standardmäßig auf 503 ab (Spring Boot).
Wie tief darf eine Readiness-Prüfung gehen?
So tief, wie es die harten Abhängigkeiten verlangen, und so flach, wie es das Zeitbudget zulässt. Die engste Frist im typischen Aufbau ist die der Container-Plattform mit einer Sekunde im Standard (Kubernetes-Dokumentation); der Lastverteiler räumt fünf Sekunden ein (AWS). Erfahrungsgemäß trägt eine Prüfung ein bis zwei harte Abhängigkeiten mit je knapp bemessener Teilfrist.
Kann ein zu strenger Health-Check selbst einen Ausfall auslösen?
Ja, und dieser Fall ist dokumentiert. Fällt mehr als die Hälfte der Instanzen durch die Prüfung, verwirft ein verbreiteter Vermittler das Ergebnis und verteilt wieder an alle - der Standardwert dieser Notbremse liegt bei 50 Prozent (Envoy). Dazu kommt der Verstärkungseffekt von Wiederholungen: Drei unabhängig wiederholende Schichten machen aus einem Klick bis zu 64 Anfragen an die Datenbank (Google SRE Book).
Wie oft sollte ein Health-Endpunkt abgefragt werden?
Das entscheidet in der Regel nicht die Anwendung, sondern die Schicht davor. Container-Plattformen fragen im Standard alle zehn Sekunden ab (Kubernetes-Dokumentation), ein Lastverteiler alle 30 Sekunden (AWS), ein anderer Anbieter über die Oberfläche dagegen alle fünf Sekunden (Microsoft) und über Vorlage alle 15 Sekunden (Microsoft). Der Endpunkt muss den engsten dieser Takte ohne spürbare Last vertragen.
Was gehört auf keinen Fall in die Antwort eines Health-Endpunkts?
Alles, was die Aufklärung eines Angriffs erleichtert: Bibliotheks- und Systemversionen, interne Hostnamen und Adressen, Verbindungszeichenfolgen, Zugangsdaten und Stapelspuren. Ein öffentlich erreichbarer Pfad trägt typischerweise nur den Gesamtzustand und einen Zeitstempel; die Teilzustände gehören auf einen intern erreichbaren Pfad.

Passend in XICTRAQ

Funktionen

Anleitungen

In 60 Sekunden starten

Lassen Sie XICTRAQ Ihre Website bewachen.

Dauerhaft kostenloser Plan verfügbar. Keine Kreditkarte, keine Installation, keine versteckten Kosten.