Ihre PHP-Anwendung – ein zerbrechlicher Schmetterling? Zeit, das im Kampf zu testen
\n\nStellen Sie sich vor: Freitagabend. Sie haben gerade das lang erwartete Release gestartet. Alles funktioniert perfekt. Sie gießen sich Tee ein, öffnen Telegram... Und dann fällt die Datenbank aus. Oder Redis. Oder eine externe API. Kommt Ihnen das bekannt vor? Wenn nicht – dann sind Sie wahrscheinlich einfach noch nie auf echtes Chaos gestoßen.
\n\nIn der Welt der PHP-Entwicklung ist es üblich, auf "Hoffnung" zu setzen. Wir schreiben Code, decken ihn mit Unit-Tests ab, manchmal sogar mit Integrationstests. Aber was passiert, wenn alles nicht nach Plan läuft? Wenn der Server Pakete verliert, die Datenbank mit einer Verzögerung von 10 Sekunden antwortet oder das Dateisystem überläuft?
\n\nHier kommt Chaos Engineering ins Spiel – eine Disziplin, die aus der Welt von Netflix und großen verteilten Systemen stammt. Aber beeilen Sie sich nicht, den Artikel zu schließen: Das funktioniert auch für normale PHP-Anwendungen, selbst wenn Sie einen Monolithen mit Laravel oder Symfony haben.
\n\nWas ist Chaos Engineering und warum braucht es ein PHP-Entwickler?
\n\nChaos Engineering ist die Praxis, Experimente an einem System durchzuführen, um Schwachstellen zu identifizieren, bevor sie sich in einem echten Ausfall manifestieren. Sie führen absichtlich Störungen ein (schalten Dienste ab, verzögern Antworten, töten Prozesse) und beobachten, wie sich Ihre Anwendung verhält.
\n\nViele denken: "Ich habe eine einfache PHP-Anwendung, warum sollte ich das brauchen?". Aber seien wir ehrlich:
\n\n- \n
- Verlässt sich Ihr Code auf externe APIs? Ja. \n
- Haben Sie Caching über Redis oder Memcached? Ja. \n
- Nutzen Sie Warteschlangen (RabbitMQ, Kafka, SQS)? Höchstwahrscheinlich ja. \n
- Datenbank – MySQL/PostgreSQL? Ja. \n
Jeder dieser Punkte ist ein potenzieller Ausfallpunkt. Und die Ausfallsicherheit von PHP-Anwendungen wird erst in dem Moment getestet, in dem etwas kaputt geht. Chaos Engineering ermöglicht es Ihnen, derjenige zu sein, der kaputt macht, und nicht derjenige, der repariert.
\n\nGrundlegende Prinzipien des Chaos Engineering
\n\nBevor Sie Code schreiben, merken Sie sich drei Hauptregeln:
\n\n- \n
- Fangen Sie klein an. Schalten Sie nicht sofort die gesamte Datenbank ab. Beginnen Sie mit einer einzigen Verbindung. \n
- Haben Sie eine Hypothese. "Wenn Redis ausfällt, sollte die Anwendung funktionieren, aber langsamer sein" – das ist eine Hypothese. Überprüfen Sie sie. \n
- Automatisieren Sie den Rollback. Haben Sie immer einen Plan, um zum Normalzustand zurückzukehren. \n
Kommen wir nun zu realen Beispielen in PHP.
\n\nBeispiel 1: Emulation einer Datenbankverzögerung
\n\nAngenommen, Sie haben eine typische Abfrage an MySQL. Sie verwenden PDO. Wie überprüfen Sie, was passiert, wenn die Datenbank plötzlich anfängt zu "trödeln"?
\n\nDer einfachste Weg ist, eine Middleware oder einen Wrapper für PDO zu schreiben, der eine zufällige Verzögerung hinzufügt. Hier ist ein Beispiel:
\n\n<?php\nclass ChaoticPDO extends PDO {\n private float $chaosProbability;\n private int $maxDelayMs;\n\n public function __construct(\n string $dsn, \n ?string $username = null, \n ?string $password = null, \n ?array $options = null,\n float $chaosProbability = 0.1, // 10% der Abfragen werden "trödeln"\n int $maxDelayMs = 5000 // maximal 5 Sekunden Verzögerung\n ) {\n parent::__construct($dsn, $username, $password, $options);\n $this->chaosProbability = $chaosProbability;\n $this->maxDelayMs = $maxDelayMs;\n }\n\n public function query(string $query, ?int $fetchMode = null, mixed ...$fetchModeArgs): PDOStatement|false\n {\n $this->maybeInjectDelay();\n return parent::query($query, $fetchMode, ...$fetchModeArgs);\n }\n\n private function maybeInjectDelay(): void {\n if (mt_rand() / mt_getrandmax() < $this->chaosProbability) {\n $delay = mt_rand(100, $this->maxDelayMs);\n usleep($delay * 1000);\n // Protokollieren für die Überwachung\n error_log("[CHAOS] Injected delay of {$delay}ms in database query");\n }\n }\n}\n\n// Verwendung\n$pdo = new Ch