mehr als nur ein 200er Status Code
Ein Health Check, der nur prüft, ob der Webserver antwortet, meldet einen Shop als gesund, obwohl die Datenbank blockiert, die Suche down ist oder die Message Queue voll läuft. Ein durchdachter Health Check Endpoint prüft echte Abhängigkeiten und verhindert, dass ein Load Balancer weiter Traffic auf einen defekten Node schickt.
Inhaltsverzeichnis
- 1. Warum ein Health Check mehr als ein Ping sein muss
- 2. Liveness und Readiness: zwei unterschiedliche Fragen
- 3. Einen eigenen Health Check Controller in Magento bauen
- 4. Datenbank und Redis in den Check einbeziehen
- 5. Suche und Message Queue prüfen, ohne den Shop zu belasten
- 6. Health Checks in Kubernetes Probes einbinden
- 7. Sicherheit: Health Check Endpoint absichern
- 8. Timeouts, Caching und Kaskadeneffekte vermeiden
- 9. Health-Check-Strategien im Vergleich
- 10. Zusammenfassung
- 11. FAQ
1. Warum ein Health Check mehr als ein Ping sein muss
Viele Magento Installationen verlassen sich auf einen einfachen HTTP-Aufruf auf die Startseite, um zu entscheiden, ob ein Node gesund ist. Das Problem: Die Startseite kann durch den Full Page Cache ausgeliefert werden, selbst wenn die Datenbank dahinter längst nicht mehr erreichbar ist. Ein solcher Health Check meldet dauerhaft grün, während der Checkout, der nicht gecacht wird, für echte Kunden bereits fehlschlägt.
Ein durchdachter Health Check prüft stattdessen gezielt die Abhängigkeiten, von denen der Betrieb tatsächlich abhängt: die Datenbankverbindung, den Redis-Cache, die Suchmaschine und die Message-Queue-Verbindung. Erst wenn diese Prüfungen erfolgreich sind, meldet der Health Check Endpoint den Node als bereit für Traffic. Diese Präzision ist der Unterschied zwischen einem Monitoring, das echte Ausfälle erkennt, und einem, das nur Schein-Sicherheit vermittelt.
Für produktive Magento Shops mit mehreren Application-Servern hinter einem Load Balancer ist ein eigener Health Check keine Kür, sondern Grundvoraussetzung für sauberes Rolling-Deployment und automatisches Failover. Ohne ihn bleibt jedem Operator nur die Wahl zwischen blindem Vertrauen und manuellem Eingriff bei jedem Vorfall.
2. Liveness und Readiness: zwei unterschiedliche Fragen
Ein zentrales Missverständnis bei Health Checks ist, Liveness und Readiness als dasselbe zu behandeln. Liveness beantwortet die Frage, ob der Prozess überhaupt noch läuft und reagiert, unabhängig davon, ob er gerade Anfragen sinnvoll bedienen kann. Readiness beantwortet die Frage, ob der Node aktuell bereit ist, Traffic zu empfangen, weil alle notwendigen Abhängigkeiten erreichbar sind.
Der Unterschied wird konkret, wenn die Datenbank kurzzeitig nicht erreichbar ist: Der PHP-Prozess selbst läuft weiterhin einwandfrei, Liveness bleibt also grün. Readiness dagegen muss auf rot springen, damit der Load Balancer keinen neuen Traffic mehr auf diesen Node schickt, während bestehende Verbindungen kontrolliert auslaufen. Ein Health Check Endpoint, der beide Konzepte vermischt, riskiert entweder unnötige Neustarts bei Liveness-Fehlern oder blindes Weiterleiten von Traffic bei Readiness-Problemen.
3. Einen eigenen Health Check Controller in Magento bauen
Magento bringt bereits einen einfachen health_check.php mit, der aber nur grundlegende Verfügbarkeit prüft. Für einen aussagekräftigen Health Check lohnt sich ein eigener Controller, der über eine dedizierte Route erreichbar ist und strukturiert JSON mit dem Status jeder einzelnen Abhängigkeit zurückgibt. Dieser Ansatz macht Probleme sofort diagnostizierbar, statt nur einen binären Status zu liefern.
Wichtig ist, den Controller unabhängig vom regulären Frontend-Layout zu halten, damit ein Ausfall im Layout-System selbst den Health Check nicht mit in den Abgrund reißt. Eine direkte Antwort ohne Block-Rendering und ohne Template-Engine reduziert die Angriffsfläche für Fehler im Health Check selbst erheblich.
<?php
declare(strict_types=1);
namespace Mironsoft\Observability\Controller\Health;
use Magento\Framework\App\Action\HttpGetActionInterface;
use Magento\Framework\App\ResponseInterface;
use Magento\Framework\Controller\Result\JsonFactory;
use Mironsoft\Observability\Model\HealthCheck\CheckPool;
/**
* Runs all registered dependency checks and returns a structured JSON result.
*/
class Index implements HttpGetActionInterface
{
/**
* @param JsonFactory $resultJsonFactory Factory for building JSON responses.
* @param CheckPool $checkPool Pool of registered dependency checks.
*/
public function __construct(
private readonly JsonFactory $resultJsonFactory,
private readonly CheckPool $checkPool,
) {
}
/**
* Executes every registered check and returns the aggregated status.
*
* @return ResponseInterface
*/
public function execute(): ResponseInterface
{
$results = [];
$healthy = true;
foreach ($this->checkPool->getChecks() as $name => $check) {
$result = $check->run();
$results[$name] = $result->toArray();
$healthy = $healthy && $result->isHealthy();
}
$resultJson = $this->resultJsonFactory->create();
$resultJson->setHttpResponseCode($healthy ? 200 : 503);
return $resultJson->setData(['status' => $healthy ? 'ok' : 'degraded', 'checks' => $results]);
}
}
4. Datenbank und Redis in den Check einbeziehen
Die Datenbankprüfung sollte nicht nur eine offene Verbindung testen, sondern eine minimal aussagekräftige Abfrage ausführen, etwa das Auslesen des Store-Konfigurationswerts. Eine reine Verbindungsprüfung übersieht Situationen, in denen die Verbindung besteht, aber die Datenbank durch Locks oder Replikationsverzögerung faktisch nicht arbeitsfähig ist. Der Health Check für die Datenbank misst zusätzlich die Antwortzeit und markiert den Node bereits bei deutlich erhöhter Latenz als degradiert, nicht erst beim vollständigen Timeout.
Für Redis gilt ein ähnliches Prinzip: Ein PING-Befehl allein reicht nicht aus, wenn Redis als Session-Storage konfiguriert ist und der verwendete Datenbank-Index nicht erreichbar ist. Der Health Check sollte denselben Redis-Client und dieselbe Konfiguration nutzen wie die produktive Session-Verwaltung, damit ein Konfigurationsfehler, der nur einen bestimmten Cache-Bereich betrifft, auch tatsächlich erkannt wird.
<?php
declare(strict_types=1);
namespace Mironsoft\Observability\Model\HealthCheck;
use Magento\Framework\App\ResourceConnection;
/**
* Verifies the database connection by running a lightweight, real query
* instead of just checking whether a connection object exists.
*/
class DatabaseCheck implements CheckInterface
{
private const SLOW_THRESHOLD_MS = 200;
/**
* @param ResourceConnection $resourceConnection Magento's DB connection resolver.
*/
public function __construct(private readonly ResourceConnection $resourceConnection)
{
}
/**
* Runs a minimal read query and measures its latency.
*
* @return CheckResult
*/
public function run(): CheckResult
{
$start = microtime(true);
try {
$connection = $this->resourceConnection->getConnection();
$connection->fetchOne('SELECT 1');
} catch (\Throwable $exception) {
return CheckResult::failed('database', $exception->getMessage());
}
$elapsedMs = (microtime(true) - $start) * 1000;
return $elapsedMs > self::SLOW_THRESHOLD_MS
? CheckResult::degraded('database', sprintf('slow response: %.1fms', $elapsedMs))
: CheckResult::healthy('database');
}
}
5. Suche und Message Queue prüfen, ohne den Shop zu belasten
Elasticsearch oder OpenSearch lassen sich über den Cluster-Health-Endpunkt prüfen, der ohnehin für genau diesen Zweck existiert und keine teure Suchanfrage erfordert. Ein Health Check, der stattdessen eine echte Produktsuche ausführt, erzeugt unnötige Last auf dem Suchindex und verzögert die Antwort des gesamten Checks unnötig, gerade bei großen Katalogen.
Die Message Queue, meist RabbitMQ, lässt sich über die Management-API prüfen, ob die relevanten Queues existieren und keine übermäßige Anzahl unverarbeiteter Nachrichten aufweisen. Ein Health Check, der nur die TCP-Verbindung zu RabbitMQ testet, übersieht das häufigste reale Problem: einen hängenden Consumer, der Nachrichten empfängt, aber nicht mehr verarbeitet, während sich die Warteschlange füllt.
6. Health Checks in Kubernetes Probes einbinden
In einer Kubernetes-Umgebung übersetzen sich Liveness und Readiness direkt in die entsprechenden Probe-Typen. Die Liveness Probe sollte bewusst schlank bleiben und nur prüfen, ob PHP-FPM antwortet, damit ein temporärer Datenbankausfall nicht zu einem Neustart des gesamten Pods führt, der das Problem gar nicht lösen würde. Die Readiness Probe dagegen ruft den vollständigen Health Check Endpoint mit allen Abhängigkeitsprüfungen auf.
Wichtig ist die Konfiguration von initialDelaySeconds, damit ein frisch gestarteter Pod nicht sofort als fehlgeschlagen markiert wird, während Magento noch den OPcache aufwärmt. Ein zu aggressives Probe-Intervall in Kombination mit einem teuren Health Check kann zudem selbst zur Lastquelle werden, weshalb Frequenz und Prüfungstiefe bewusst gegeneinander abgewogen werden müssen.
# Kubernetes deployment snippet for Magento application pods
livenessProbe:
httpGet:
path: /health_check.php
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 3
readinessProbe:
httpGet:
path: /rest/V1/mironsoft-observability/health
port: 8080
initialDelaySeconds: 45
periodSeconds: 15
timeoutSeconds: 5
failureThreshold: 2
7. Sicherheit: Health Check Endpoint absichern
Ein Health Check Endpoint, der Details über interne Systemzustände preisgibt, etwa Datenbank-Hostnamen oder Fehlermeldungen aus Exceptions, ist ein Informationsleck für Angreifer. Die öffentliche Variante des Endpunkts sollte nur einen aggregierten Status zurückgeben, während detaillierte Diagnosedaten nur über eine interne Route oder mit gültiger Authentifizierung sichtbar sind.
Zusätzlich sollte der Health Check nicht über die reguläre Magento-Middleware mit vollständiger Session-Initialisierung laufen, weil das unnötige Last erzeugt und potenziell Angriffsfläche über Session-Handling eröffnet. Eine schlanke, dedizierte Route außerhalb der normalen Store-View-Auflösung ist hier die robustere Wahl.
8. Timeouts, Caching und Kaskadeneffekte vermeiden
Jeder einzelne Check innerhalb des Health Check Endpoints braucht ein eigenes, kurzes Timeout. Ohne diese Begrenzung kann eine hängende Abhängigkeit, etwa eine Datenbank, die auf einen Lock wartet, den gesamten Health-Check-Aufruf blockieren und damit den Load Balancer glauben lassen, der gesamte Node sei tot, obwohl nur ein einzelner Teilcheck hängt.
Ein weiterer wichtiger Aspekt ist ein kurzes Caching der Ergebnisse, etwa für zwei bis fünf Sekunden, damit ein aggressiv pollender Load Balancer nicht bei jeder Anfrage erneut alle Abhängigkeiten prüft und damit selbst zur Lastquelle für die Datenbank wird. Der Health Check darf niemals selbst zum Performance-Problem werden, das er eigentlich aufdecken soll.
9. Health-Check-Strategien im Vergleich
Es gibt mehrere Reifegrade, wie ein Health Check für Magento umgesetzt werden kann. Die folgende Tabelle ordnet die gängigen Varianten nach Aussagekraft und Aufwand ein.
| Strategie | Aussagekraft | Risiko | Empfehlung |
|---|---|---|---|
| Startseite per HTTP prüfen | Sehr gering, oft gecacht | Verdeckt Datenbank- und Suchausfälle | Nicht als alleiniger Check nutzen |
| Nur TCP-Port-Check | Gering | Erkennt hängende Prozesse nicht | Nur als Liveness, nicht als Readiness |
| Eigener aggregierter Endpoint | Hoch, prüft echte Abhängigkeiten | Muss selbst gegen Timeouts abgesichert werden | Empfohlener Standard für Magento |
| Synthetische Transaktion (echter Checkout) | Sehr hoch, End-to-End | Erzeugt echte Bestellungen ohne Sorgfalt | Nur mit Testkonten und niedriger Frequenz |
Die pragmatische Empfehlung für die meisten Magento Betriebe ist der eigene aggregierte Endpoint, ergänzt um eine seltene synthetische Transaktion mit dedizierten Testkonten, um echte End-to-End-Funktionsfähigkeit regelmäßig, aber ohne operativen Overhead zu verifizieren.
Mironsoft
Magento Observability, Health Checks und Betriebsstabilität
Ein Health Check, dem euer Load Balancer wirklich trauen kann?
Wir bauen einen eigenen Health Check Endpoint für euren Magento Shop, der Datenbank, Cache, Suche und Message Queue prüft, sauber in Kubernetes Probes einbindet und selbst nicht zur Fehlerquelle wird.
Dependency Checks
Datenbank, Redis, Suche und Message Queue einzeln geprüft
Kubernetes-Integration
Liveness und Readiness Probes korrekt getrennt konfiguriert
Absicherung
Timeouts, Caching und Zugriffskontrolle für den Endpoint selbst
10. Zusammenfassung
Ein aussagekräftiger Health Check für Magento prüft echte Abhängigkeiten statt nur die Erreichbarkeit des Webservers. Datenbank, Redis, Suche und Message Queue müssen einzeln bewertet werden, mit eigenen Timeouts, damit ein einzelner hängender Teilcheck nicht den gesamten Node fälschlich als tot markiert. Die klare Trennung von Liveness und Readiness verhindert unnötige Neustarts bei temporären Abhängigkeitsproblemen.
In Kubernetes-Umgebungen übersetzt sich diese Struktur direkt in zwei unterschiedlich konfigurierte Probes, während der Health Check Endpoint selbst durch Caching und Zugriffskontrolle vor Missbrauch und übermäßiger Last geschützt werden muss. Wer diesen Aufwand einmal investiert, gewinnt zuverlässiges Rolling-Deployment und automatisches Failover, ohne blind auf einen einfachen Ping zu vertrauen.
Eigene Health Checks für Magento — Das Wichtigste auf einen Blick
Liveness vs. Readiness
Liveness prüft, ob der Prozess läuft. Readiness prüft, ob alle Abhängigkeiten erreichbar sind. Nie vermischen.
Echte Abhängigkeiten prüfen
Datenbank mit echter Query, Redis mit produktivem Client, Suche über Cluster-Health, Queue über Management-API.
Timeouts pro Check
Jede Einzelprüfung braucht ein kurzes eigenes Timeout, sonst blockiert eine hängende Abhängigkeit den gesamten Check.
Absicherung
Keine internen Details in der öffentlichen Antwort, kurzes Ergebnis-Caching gegen aggressive Poller.