4. června 2026, Luboš Zápotočný
Proč pokladna padá, když servery běží na 10 %
Servery mají rezervu, pokladna přesto selhává. Zámky v databázi, cache stampede a synchronní platební volání: poruchy, které autoscaling nevyřeší.
Je to ten nejvíc matoucí incident, jaký může e-commerce tým zažít. Kampaň odstartuje, pokladna začne padat na timeouty a dashboardy trvají na tom, že je všechno v pořádku: CPU na 10 %, paměť v klidu, rezervy dost. Instinkt velí přidat servery. Nové servery naběhnou, zůstanou nevytížené vedle stávajících a výpadek pokladny trvá dál.
Zmatek pramení ze špatného mentálního modelu. Zátěž má totiž dvě složky: práci a čekání. Vaše servery stojí ve frontě, a fronty na grafu CPU vidět nejsou.
Nejčastější příčiny
Soupeření o zámky v databázi. Pokladna je místo, kde e-shop přestává číst a začíná zapisovat: rezervovat sklad, založit objednávku, uložit adresu. Tyhle zápisy se serializují na řádkových zámcích, a provoz z kampaně se koncentruje na těch samých pár řádcích. Sto zákazníků procházejících pokladnou během jedné akce se serializuje na těch samých horkých řádcích: sekvenčních čítačích objednávek, tabulkách objednávek a košíků, rezervovaném skladu. Každá transakce drží své zámky, zatímco čeká na jinou práci. Propustnost se zhroutí, i když vytížení CPU zůstává nízké. Na Magentu to má typický projev: hlášky o čekání na zámcích a deadlocích, které ráno po výprodeji plní logy.
Cache stampede. Horká položka v cache (stránka kategorie, na kterou míří každá reklama) expiruje uprostřed špičky. Každý požadavek, který ji mine, teď generuje stránku znovu, všechny současně, a zatěžuje databázi identickými drahými dotazy. Cache, díky které byl e-shop rychlý, teď způsobuje jeho výpadek, a kdy k tomu dojde, určuje její TTL.
Synchronní volání třetích stran v cestě pokladny. Sazby dopravy, autorizace platby, výpočet daně, anti-fraud kontrola. Každé z nich je síťové volání do cizího systému, provedené zatímco váš worker drží spojení a často i databázovou transakci. Když jeden poskytovatel pod stejnou kampaňovou zátěží zpomalí z 200 ms na 10 sekund, každý worker postupně uvízne uvnitř toho volání. Kdy pokladna selže, teď neurčuje váš provoz, ale okamžité zpomalení na straně dodavatele.
Vyčerpání workerů a spojení. Tři problémy výše sdílejí společný zesilovač: workery, které čekají, pořád zabírají svůj slot i databázové spojení. PHP-FPM procesy nadimenzované na běžný provoz se zaplní zablokovanými požadavky, nové požadavky nedostanou worker ani spojení vůbec, a najednou selže všechno, co ještě potřebuje PHP worker, ať už na té stránce zbývá jakkoli málo práce.
Ani jeden z těch čtyř problémů není problém hardwaru, a právě proto autoscaling nepomůže: nové instance se zařadí do stejné fronty na stejný řádkový zámek za stejným pomalým dodavatelem. Výsledkem je jen to, že čeká víc serverů najednou.
Jak to vidět předem
Diagnostický posun je od vytížení k času: kde tráví požadavek pokladny své milisekundy? Prací, nebo čekáním na zámky, cache a cizí API? Distribuovaný tracing na to odpovídá přímo; slow-query log plus čítače čekání na zámcích v databázi na to odpovídají levně. Pokud před další kampaní přidáte jediný graf, ať jsou to čekání na zámcích.
Opravy plynou z diagnózy a většina z nich je neokázalá: timeouty na každém volání třetí strany a cachované fallbacky tam, kde zastaralá odpověď neuškodí (mírně zastaralá sazba dopravy nevadí, autorizace platby ale musí proběhnout naživo), ochrana proti stampede, aby horký klíč přestavoval jeden proces, zatímco ostatní servírují starší verzi, přesun nepodstatných zápisů mimo transakci do fronty a rezervaci skladu tak pozdě ve funnelu, jak to byznys dovolí, místo držení od košíku. Které z toho je podstatné pro váš e-shop, je empirická otázka. Přesně na ni odpovídá audit výkonu z vašich trace, ne z obecných pouček, a přesně tenhle typ oprav pak naše práce na DevOps udrží v chodu.
Výpadky při kampaních mají málokdy příčinu v kapacitě; většinou jde o souběh. Než začnete nakupovat servery, podívejte se do trace, kde požadavky doopravdy čekají.