Reverzní proxy

Miroslav Suchý 25. 10. 2004

Co je to reverzní proxy a jak vám zvedne výkon vašeho web serveru. Jak nastavit apache pro použití reverzní proxy.

Nedávno jsem přemýšlel (a konečně proč ne?), jak zvýšit výkon našeho webového serveru. Situace začínala být neunosná zejména v množství zabrané paměti, protože na swapu leželo mnoho dat.

Abych byl konkrétnější, popíšu vám počáteční konfiguraci:

Požadavky vyřizoval apache (1.3), který má plno modulů (php, mod_perl, mnoho perlovských knihoven) a vykazoval značné paměťové nároky (40–80 MB rezidentní + 150 MB sdílených dat na proces), ve špičce bylo potřeba i 100 procesů a stejně se některé musely odmítat (modulem tsunami), protože zátěž byla příliš velká a docházelo k výraznému swapovaní. Protože (100 procesů * 60 MB) + 150 MB = 6 GB paměti a server měl jenom 2 GB paměti.

Na další 2 GB momentálně nebylo a stejně by to problém nevyřešilo, takže přišla na řadu optimalizace. Velmi dobrou inspirací mi byla i stránka develooper.com/mod­perl/performan­ce_tuning.html, kde jsem našel zajímavé řešení nazvané reverzní proxy.

Klasickou proxy jistě každý čtenář rootu zná. Zatímco normální proxy je co nejblíže ke koncovému uživateli, reverzní proxy je na druhé straně „drátu“. Je tedy bezprostředně před aplikačním serverem.

A k čemu je to vlastně dobré, mít před vlastním serverem ještě jednu vrstvu? Uvedu opět příklad ze života:

Na našem serveru vyřizujeme 90 požadavků za sekundu a počítáme každou milisekundu. Podívejme se, co vlastně server nejvíce zdržuje. HTTP hlavička. Ta má řádově stovku bytů. Načtení hlavičky o velikosti 400 bytů trvá sedm milisekund, což je 63 % doby, kterou se server může maximalně zabývat celým požadavkem! No a pokud vám vadí, že na čtení dat z portu vám slouží několik desítek megabajtů veliké monstrum, tak máte první důvod, proč se zabývat reverzní proxy.

Revezní proxy, která může být velmi malá, načte požadavek od uživatele, a až jej celý načte, předá ho dále na aplikační server. I kdyby to bylo po 100megabitové síti, stráví aplikační server komunikací s uživatelem tisíckrát menší dobu. Pokud navíc generování stránky je netriviální úkol, můžete použít reverzní proxy s cachovaním a váš velký aplikační server nemusí trávit svůj drahocenný čas poskytováním statických stránek.

Než se podíváme, jak to celé nastavit, dovolím si uvést náš koncový stav po optimalizaci:

Nyní na serveru běží jako reverzní proxy apache (2.0) s paměťovým modelem worker a je zapnut pouze mod_proxy a nic jiného. Paměťové nároky jsou 13 MB RES + 543 MB SHR na proces. Je spuštěno sedm procesů (každý z nich má 65 threadů). Tj. (7 procesů * 13 MB) + 5­43 MB = 634 MB. Apache2 posílá své požadavky na localhost, kde běží původní apache. Těch ovšem stačí pouhých 30! Celkem je tedy paměťová náročnost 634 MB (apache2) + (30 * 60 MB) + 1­50 MB (apache1.3)) = 2,5 GB. Tj. 42 % původní hodnoty. A to prosím s novým nastavením máme zapnuté KeepAlive (samozřejmě jenom na proxy), takže kvalitativní zlepšení by měli poznat i koncoví uživatelé. U původního řešení by bylo čekání několik sekund (sekund!! ježíškovy očička!), po skončení dotazu naprosto nemyslitelné.

Nastavení

Pokud stále ještě čtete, tak vás to asi stále zajímá a chtěli byste vědět, jak to celé bezbolestně nastavit na vašem webu. Tak jdeme na to.

Jako reverzní proxy jsem použil apache2. Původně jsem chtěl použít squid, ale nepodařilo se mi s ním rozchodit virtualní hosting. Proxy, ať už to je apache, squid, nebo jiný program, připojíte na původní IP adresu na port 80 místo původního web serveru. Tak zajistíte, že pro koncového uživatele to bude plně transparentní a nemusí si nikde nic nastavovat, což by v praxi ani nešlo.

Abych předešel nedorozumění: v dalším textu budu používat dva různé apache. Jeden jako reverzní proxy a budu ho označovat jako apache2, druhý coby původního apache, který slouží jako aplikační server, a budu ho označovat jednoduše apache.

V nastavení apache2 zaveďte moduly mod_rewrite a mod_proxy. Pozor: v debianní implicitní konfiguraci zároveň mod_proxy natahuje i mod_cache, který možná nebudete potřebovat. Já jsem ho nepotřeboval, takže se o něm nebudu rozepisovat. Zapněte volbu

ProxyPreserveHost On

Ta zajistí, že apache2 zachová hlavičku Host: z původního požadavku, a můžete tak bez problémů používat virtual hosting. Zapněte přepisování:

RewriteEngine On
 RewriteCond  %{REQUEST_URI}    !^/proxy-status
 RewriteRule (.*) http://localhost$1 [P]
ProxyPassReverse / http://localhost/

První řádek zapne přepisování adres. Druhý řádek řekne, že se to netýká dokumentu /proxy-status. Na tuto adresu vám doporučuji pověsit modul mod_status, abyste měli přehled o stavu apache2 pro ladění parametrů, jako jsou MaxSpare a MinSpare. Třetí řádek řekne, že všechny zbývající dotazy se mají přesměrovat přes engine proxy ([P]) na localhost. Poslední řádek zajistí změnu HTTP přesměrování v hlavičkách Location a Content-Location, které obsahují odkaz na localhost zpět na původní server.

Původní apache navěste na localhost:

BindAddress 127.0.0.1

Pokud používáte virtuální hosting, musíte asi změnit i direktivu NameVirtualHost:

NameVirtualHost *

a všechny direktivy VirtualHost:

<VirtualHost *>

Kdo dosud používal hvězdičkovou notaci, změní jenom BindAdress a má o práci méně.

No a mohli bychom být hotovi. Kdo však chce nějak pracovat s IP adresami uživatelů, nechť čte dále. Příchozí požadavky na apache totiž přirozeně přicházejí z 127.0.0.1, což se vám asi nebude líbit. Takže jako řešení jsem použil modul rpaf, který podvrhne apachi jako IP adresu tu, která je uvedena v hlavičce X-Forwarded-For. Nastavení je jednoduché:

<IfModule mod_rpaf.c>

        RPAFenable On
        RPAFproxy_ips 127.0.0.1
</IfModule>

Direktiva RPAFproxy_ips říká, že se bude měnit IP adresa jenom od proxy serverů uvedených v parametru.

Tak a nyní je to konečně vše. Pokud máte více serverů, můžete si trošku více vyhrát s přepisováním a postavit reverzní proxy pro více serverů.

P.S. Pokud byste jako proxy chtěli vyzkoušet squid, tak zdenajdete návod, jak na to (v angličtině). Nicméně jak jsem se již zmiňoval, nepodařilo se mi se squidem rozjet virtuální hosting.

Našli jste v článku chybu?
Měšec.cz: Se stavebkem k soudu už (většinou) nemusíte

Se stavebkem k soudu už (většinou) nemusíte

DigiZone.cz: Výzkum FTV Prima. HbbTV má úspěch

Výzkum FTV Prima. HbbTV má úspěch

Měšec.cz: Udali ho na nelegální software a přišla Policie

Udali ho na nelegální software a přišla Policie

120na80.cz: Bonbon si schovejte na přistání

Bonbon si schovejte na přistání

DigiZone.cz: Kauza technik: oficiální vyjádření Novy

Kauza technik: oficiální vyjádření Novy

Vitalia.cz: Sobotní masakr žrádla, chlastu a zábavy

Sobotní masakr žrádla, chlastu a zábavy

DigiZone.cz: Přechod na DVB-T2? Kolem miliardy...

Přechod na DVB-T2? Kolem miliardy...

Měšec.cz: Test: Výběry z bankomatů v cizině a kurzy

Test: Výběry z bankomatů v cizině a kurzy

Podnikatel.cz: Fotogalerie: Jesenka už má skoro 50 let

Fotogalerie: Jesenka už má skoro 50 let

Vitalia.cz: Tohle je Břicháč Tom, co zhubnul 27 kg

Tohle je Břicháč Tom, co zhubnul 27 kg

Lupa.cz: eIDAS: Nepřehnali jsme to s výjimkami?

eIDAS: Nepřehnali jsme to s výjimkami?

Podnikatel.cz: Český zákazník nakupuje v čínských e-shopech

Český zákazník nakupuje v čínských e-shopech

Měšec.cz: Do ostravské MHD bez jízdenky. Stačí vaše karta

Do ostravské MHD bez jízdenky. Stačí vaše karta

Měšec.cz: TEST: Vyzkoušeli jsme pražské taxikáře

TEST: Vyzkoušeli jsme pražské taxikáře

Lupa.cz: Největší torrentový web KickassTorrents padl

Největší torrentový web KickassTorrents padl

Vitalia.cz: Jak na domácí zmrzlinu?

Jak na domácí zmrzlinu?

120na80.cz: Úpal vs. úžeh. Co dělat?

Úpal vs. úžeh. Co dělat?

Vitalia.cz: Patří maso do dětského jídelníčku?

Patří maso do dětského jídelníčku?

Podnikatel.cz: Daň z nemovitosti? Změny budou v říjnu

Daň z nemovitosti? Změny budou v říjnu

Lupa.cz: EU začala prověřovat bezpečnost open-source

EU začala prověřovat bezpečnost open-source