Zum Inhalt springen
Zapolu

4. Juni 2026, Luboš Zápotočný

Warum der Checkout bei 10 % Serverlast ausfällt

Server im Leerlauf, Checkout nicht erreichbar. Lock-Contention, Cache-Stampedes, synchrone Payment-Calls: Ausfallmuster, gegen die Autoscaling nicht hilft.

Es ist einer der am schwersten einzuordnenden Incidents für ein E-Commerce-Team. Die Kampagne geht live, der Checkout läuft in Timeouts, und die Dashboards zeigen unauffällige Werte: CPU bei 10 %, Speicher normal, reichlich freie Kapazität. Die naheliegende Reaktion ist, Server zu ergänzen. Die neuen Server laufen ebenfalls im Leerlauf, und der Checkout ist weiterhin nicht erreichbar.

Die Verwirrung kommt von einem falschen mentalen Modell. Last hat zwei Komponenten: Arbeit und Warten. Ihre Server verbringen die Zeit in Warteschlangen, und Warteschlangen tauchen auf keinem CPU-Graphen auf.

Die häufigsten Ursachen

Lock-Contention in der Datenbank. Der Checkout ist die Stelle, an der der Shop aufhört zu lesen und anfängt zu schreiben: Bestand reservieren, Bestellung anlegen, Adresse speichern. Diese Writes serialisieren sich auf Row Locks, und Kampagnen-Traffic konzentriert sich auf dieselben wenigen Zeilen. Hundert Kunden, die während derselben Kampagne den Checkout durchlaufen, serialisieren sich auf denselben heißen Zeilen: den Zählern der Bestellnummernsequenz, den Bestell- und Warenkorbtabellen, dem Bestand, der gerade reserviert wird. Jede Transaktion hält ihre Locks, während sie auf andere Arbeit wartet. Der Durchsatz kollabiert, während die CPU kaum etwas zu tun hat. Auf Magento hat das eine bekannte Signatur: die Lock-Wait- und Deadlock-Meldungen, die am Morgen nach dem Sale die Logs füllen.

Cache-Stampedes. Ein heißer Cache-Eintrag, etwa die Kategorieseite, auf die jede Anzeige zeigt, läuft mitten im Peak ab. Jeder Request, der den Eintrag jetzt nicht mehr vorfindet, regeneriert die Seite gleichzeitig und belastet die Datenbank mit identischen teuren Queries. Der Cache, der den Shop schnell gemacht hat, wird zur Ursache des Ausfalls, und zwar nach einem Zeitplan, den seine eigene TTL vorgibt.

Synchrone Drittanbieter-Calls im Checkout-Pfad. Versandkosten, Zahlungsautorisierung, Steuerberechnung, ein Anti-Fraud-Check: jeweils ein Netzwerkaufruf in das System von jemand anderem, während Ihr Worker eine Connection und oft eine Datenbanktransaktion hält. Wird ein Anbieter unter derselben Kampagnenlast von 200 ms auf 10 Sekunden langsam, wartet nach und nach jeder Worker in diesem Aufruf. Ob Ihr Shop ausfällt, hängt jetzt an einem Anbieter, auf den Sie keinen Einfluss haben.

Erschöpfte Worker und Connections. Die drei Probleme oben teilen sich einen Verstärker: Worker, die warten, belegen trotzdem ihren Slot und ihre Datenbank-Connection. PHP-FPM-Prozesse, dimensioniert für gewöhnliche Wochentagslast, füllen sich mit blockierten Requests, neue Requests erhalten weder einen Worker noch eine Connection, und der Ausfall erfasst jede Seite, die noch einen PHP-Worker braucht, so wenig Arbeit diese Seite auch macht.

Keines der vier Probleme ist ein Hardware-Problem, weshalb Autoscaling Sie nicht rettet: Neue Instanzen stellen sich in dieselbe Schlange vor denselben Row Lock hinter demselben langsamen Anbieter. Zusätzliche Kapazität erhöht nur die Zahl der wartenden Instanzen.

Wie Sie es frühzeitig erkennen

Für die Diagnose zählt weniger die Auslastung als die Zeit: Wohin gehen die Millisekunden eines Checkout-Requests, in Arbeit oder in Warten auf Locks, Caches und Drittanbieter-APIs? Distributed Traces beantworten das direkt; ein Slow-Query-Log plus die Lock-Wait-Zähler der Datenbank beantworten es günstig. Wenn Sie vor der nächsten Kampagne nur einen einzigen Graphen ergänzen, nehmen Sie Lock-Waits.

Die Fixes folgen aus der Diagnose, und die meisten sind unspektakulär: Timeouts auf jedem Drittanbieter-Call und gecachte Fallbacks überall dort, wo eine veraltete Antwort unschädlich ist (eine leicht veraltete Versandkostenauskunft schadet nicht, eine Zahlungsautorisierung muss dagegen live erfolgen), Stampede-Schutz, damit ein Prozess den heißen Key neu baut, während die anderen den alten Stand ausliefern, die Verlagerung nicht essenzieller Writes aus der Transaktion in eine Queue, und die Reservierung des Bestands so spät im Funnel, wie es das Geschäft erlaubt, statt ihn schon ab dem Warenkorb zu halten. Welche davon für Ihren Shop zählen, ist eine empirische Frage: die Sorte, die ein Performance-Audit mit Ihren Traces beantwortet statt mit Vermutungen, und die Sorte, die unsere DevOps-Arbeit anschließend dauerhaft macht.

Hinter fast allen Kampagnen-Ausfällen steckt am Ende Concurrency, nicht fehlende Kapazität. Prüfen Sie deshalb zuerst einen Trace, bevor Sie zusätzliche Server beschaffen.