503 – Service Temporarily Unavailable

Stavový kód 503 – Service Temporarily Unavailable se objevuje v případě, kdy server vyčerpá přidělené prostředky. U moderních sdílených webhostingů to většinou znamená, že jste vyčerpali přidělená volná PHP vlákna. Respektive je vyčerpal někdo jiný s kým sdílíte výkon. Spíše se s touto chybou ale setkáte u VPS (virtual private server) popřípadě VMS (virtual managed server), kde máte přidělené virtuální procesory. Nejlevnější varianty, které vám parametry v pohodě stačí mají většinou procesor jeden. U sdílených webhostingů je často více volného výkonu než u nejlevnějších virtuálních serverů.

Jak to tedy funguje v praxi. Dejme tomu, že máte přidělený výkon odpovídající dvěma vláknům PHP. Váš WordPress se načítá 0,5 vteřiny. Za vteřinu tedy odbaví server 2 návštěvníky na jedno vlákno, tedy 4 na obě vlákna. Ty které nestíhá začne řadit do fronty. Jejich prohlížeč bude čekat na odpověď serveru. Pokud fronta bude narůstat a server nebude stíhat, začne vracet chybu 503 – Service Temporarily Unavailable.

Do limitu PHP vlákna se totiž počítá jen běh PHP skriptu, což je až na výjimky (například volání přes Ajax) takzvaný TTFB (time to first byte) – čas od požadavku internetového prohlížeče, který pošle na server, do doby než obdrží první bit zpátky.

V reálných podmínkách však váš hosting spíše shodí nevychovaný robot, chyba ve skriptu anebo nějaké přetížení.

Nevychovaný robot #

Pokud používáte cachovací plugin není problém, aby se TTFB pohybovala v stovkách milisekund. Dokonce se základními, dobře optimalizovanými pluginy a vhodným cachovacím pluginem se dostanete pod 100ms. PHP vláken bývá kolem 5. Takže nárazová návštěvnost váš WordPress jen tak nedostane. Problém však jsou roboti.

Takový robot si stáhne seznam všech stránek na vašem webu (například ze souboru sitemap.xml) a pak z nich začne stahovat zdrojový kód. Aby to zvládl rychleji, tak stahuje i několik stránek naráz. V reálu tak posílá desítky požadavků na server za vteřinu. Navíc problém je v tom, že požaduje i stránky, na kterých už delší dobu nikdo nebyl a nejsou v cache anebo se na ně cachování nevztahuje (výsledky vyhledávání, podstránky diskuzí atd.) V reálu tak tento robot dokáže velmi rychle vyčerpat nejen PHP vlákna, ale i zatížit disk, protože nutí cachovací plugin vytvořit dočasný obraz celého webu.

Obrana je zde totožná jako u DoS útoku. Určí se nějaký počet maximálních požadavků na server z určité IP adresy. Pokud bude překročen, tak přidat IP adresu na black list a na všechny požadavky odpovídat 403. Dá se to řešit takto přes .htaccess. Pokud máte sdílený webhosting a situace se opakuje z více IP adres kontaktujte svého poskytovatele.

Chyba ve skriptu #

Nejčastěji se vám začne objevovat stavový kód 503 kvůli chybě ve skriptu. Například se skript zacyklí. Pokud je max_execution_time běhu skriptu třeba 30 vteřin, tak po celou tuto dobu je jedno PHP vlákno zabráno. Takže stačí u takovéhoto skriptu dát 5x obnovit a všechny zdroje jsou vyčerpány než uběhne 30 vteřin od spuštění skripty.

Přetížení #

Přetížení většinou způsobují špatně optimalizované skripty. Například když stahujete data z RSS zdroje pokaždé když je potřebujete. Přitom je potřebujete aktualizovat jen jedenkrát za den. Správné řešení je stáhnout data k sobě, zpracovat a uložit třeba do databáze. Pokaždé když budou potřeba je můžete vytáhnout z databáze, což je o dost jednodušší než se spojovat s cizím serverem a data pokaždé znovu připravit. Popřípadě rovnou předgenerovat. To se hodí zvláště když byste do databáze ukládali stovky položek a nebylo třeba je v budoucnu třídit anebo s nimi pracovat jako jednotlivými položkami.

Mimo dosah uživatelů by také měly být všechny skripty, které jsou náročné na zpracování dat. Například po kliknutí na tlačítko aktualizovat dojde k přepočtům dat. Návštěvník se může „zamyslet“ a klikat na aktualizovat pořád dokola. Místo toho zvolte CRON, který skript spustí v pravidelných internvalech.

Mezi další přetěžovače patří databáze v kombinaci s PHP. Někteří vývojáři věří více PHP než SQL. Takže různé přepočítávání řeší v PHP skriptu položku za položkou. Přitom v SQL by to zvládl jeden doraz daleko rychleji. Samozřejmě práce s objemnějšími tabulkami má určitou režii. Nezapomínejte na indexy, optimalizaci tabulek a hlavně navrhnout vhodnou architekturu.

Nahrávání velkých souborů přes PHP funkce readfile() a file_get_contents() také zabere jedno PHP vlákno. Práce se soubory řešte mimo akce uživatele.

Hledání chyb a optimalizace #

Základem je zjistit, který skript bere nejvíce systémových prostředků. Tedy trvá nejdéle. K tomu slouží logy (accesslog a errorlog). Jakmile identifikujete problémový skript je nutné jej optimalizovat. Několik tipů už zde zaznělo.

Čistě pro WordPress je postup obdobný. Zjistěte, který plugin anebo šablona způsobuje problém. Zkuste projít diskuze a články ve vyhledávačích jestli s daným problémovým pluginem/šablonou někdo řešil podobný problém, popřípadě kontaktujte vývojáře. Řešením je samozřejmě nahradit problémový plugin/šablonu jiným.

Samozřejmě pokud je generování stránky v mezích (v řádech vteřin), občas pomůže cachovací plugin. Různé pluginy mají odlišné možnosti nastavení. VPS mají výhodu, že si můžete nainstalovat vlastní rozšíření software k serveru podle požadavků pluginu.

Ještě stojí za zmínku napadení webu. Váš WordPress se může stát součástí botnetu a plnit útoky jako DDoS anebo spamovaní. Tyto úkoly mohou spotřebovávat značné prostředky, takže pozor na to. Opět pomůže sledování accesslog a errorlog.