Souboj webových aplikačních rozhraní

V minulém čísle jsme se v Tématu týdne věnovali problematice webových aplikačních rozhraní, která jsme ale probrali...


V minulém čísle jsme se v Tématu týdne věnovali problematice webových
aplikačních rozhraní, která jsme ale probrali pouze teoreticky. V dnešním textu
se na ně podíváme mnohem více prakticky podíváme se na jednu z nejdůležitějších
vlastností na jejich rychlost.
Jan Holec
Vlastní porovnání si ukážeme na jednoduché aplikaci pro převod českého textu (v
jednom z pěti možných kódování) na text bez diakritiky (US-ASCII). Aplikace
přijímá na vstupu dva parametry vstupní text a informaci o tom, v jakém je
kódování. Na výstup pak dodá HTML dokument obsahující výsledek převodu. Pro
každé podporované kódování češtiny má aplikace k dispozici převodní tabulku o
velikosti 256 bajtů (každá tabulka je uložena v samostatném souboru a aplikace
tyto soubory po startu v rámci inicializace načítá). Vlastní překódování pak
probíhá po znacích. Kód vstupního znaku je interpretován jako index pozice v
tabulce, na které se nachází ASCII kód odpovídajícího znaku bez diakritiky.
Navíc, protože výstupem bude HTML, je nutné znaky, které mají v HTML speciální
význam, nahradit opisnými tvary (tzv. "znakovými entitami"). Testovací platforma
Měření výkonnosti bylo provedeno na počítači třídy PC s procesorem Cyrix 6x86MX
PR200, 40MB RAM s OS Linux 2.2.16 a HTTP serverem Apache verze 1.3.12. Podpora
Fast-CGI skriptů byla realizována statickým interním modulem pro HTTP server
(mod_fastcgi, verze 2.2.4), PHP (rovněž statický modul) bylo testováno ve verzi
3.0.14 a 4.0.0. Podporu JavaServletů pak zajistila instalace balíku ApacheJServ
verze 1.1.2 v obsahu balíku lze rozlišit dvě nezávislé části: modul mod_jserv
(napsán v jazyce C), určený pro připojení k HTTP serveru, který zajišťuje
především spuštění JVM během startu HTTP serveru, jeho udržení v chodu a
vypnutí, má-li být server ukončen. Vlastní Apache JServ je aplikace napsaná v
Javě, kterou mod_jserv spustí uvnitř JVM. Z pohledu Apache funguje v podstatě
jako malý nezávislý server (tzv. "servlet engine"). Obě části spolu komunikují
přes TCP/IP spojení speciálním protokolem (Apache JServ Protocol, AJP). Přijde-
li na HTTP server požadavek týkající se servletu, mod_jserv jej převede na
vlastní požadavek vůči JServu. Pro poslední možnost Java Server Pages byl
použit balík GnuJSP 1.0.0, který vyhovuje verzi 1.0 sunovské specifikace.
Vlastní CGI skript byl napsán v Perlu (s využitím perlovského modulu CGI, k
dispozici na CPAN), stejně tak i Fast-CGI skript (perl. modul FCGI verze 0.52 a
CGI::Fast). Výše popsaná aplikace byla postupně realizována pomocí každého z
testovaných rozhraní. Měření výkonnosti
K vlastnímu měření posloužil program ApacheBench (verze 1.3c), který je
součástí distribuce serveru Apache. Srovnání výkonnosti jednotlivých
implementací bylo provedeno realizací dostatečně velkého počtu požadavků na
každou z nich a porovnáním potřebného času v jednotlivých případech. Aby bylo k
dispozici co nejvíce systémových zdrojů, byly ukončeny před započetím testování
všechny nepotřebné programy a služby a deaktivováno síťové rozhraní eth0.
Přístup k HTTP serveru byl nadále možný pouze přes zpětnovazebné rozhraní
(loopback, IP 127.0.0.1). Také byl zakázán class autoreloading u servletů a
bylo zajištěno, aby před spuštěním příslušného testu byl Fast-CGI skript již
aktivní (spouštění interpretu Perlu u prvního požadavku na Fast-CGI skript by
negativně ovlivnilo výsledky) a aby JavaServlet i JSP již "běžely" v JVM.
Aplikace při inicializaci otevírá a načítá pět souborů. Jakmile jsou však data
načtena do diskových bufferů, náročnost této operace velmi klesá. Fakt, že
aplikace (v určité realizaci) provádí inicializaci při každém spuštění, se
potom při testech tolik neprojeví. V jiném případě by však inicializace
většinou spočívající v něčem jiném např. otevírání síťových spojení což je již
časově náročná operace, která by se již projevila. Nutnost opakované
inicializace je obecně nežádoucí vlastnost a při hodnocení výsledků testů je
třeba toto vzít v úvahu. Měření výkonu bylo provedeno postupně na variantě CGI,
Fast-CGI, PHP, JS a JSP. V každém případě bylo rozlišeno zpracování vstupu
různého rozsahu. Nejprve bylo provedeno měření na prázdném vstupu a poté se
zvětšovala délka po dvou kilobajtech až do 10 KB, byl také sledován rozdíl mezi
předáním dat metodou GET a POST. Pokaždé bylo provedeno 200 požadavků na
server, což by mělo zaručit dostatečně stabilní výsledky měření. V tabulce je
pro každou variantu testu uveden celkový čas, který HTTP server potřeboval k
vyřízení tohoto množství požadavků a průměrný počet požadavků vyřízených za
jednotku času. Server Apache má vestavěné omezení na délku URL, proto není
možné předávat příliš velké množství dat metodou GET. Varianta CGI
Se zvětšujícím se rozsahem vstupních dat roste doba zpracování přibližně
lineárně. Avšak i v případě, kdy nepředáváme žádná data ke zpracování, trvá
vyřízení požadavku poměrně dlouho. To je způsobeno tím, že s každým novým
požadavkem se musí spouštět a inicializovat interpret Perlu, načítat se z disku
a překládat se musí i vlastní skript. Přestože CGI skripty přijímají data z
požadavku GET jinak než z POST (proměnné prostředí vs. standardní vstup), na
výkonnost aplikace to nemá vliv. V případě, že na CGI skript přichází více
souběžných požadavků, jsou vyřizovány samostatnými procesy Apache a každý z
nich spustí novou instanci CGI-skriptu, což výrazně zvyšuje zátěž systému.
Varianta Fast-CGI
S prázdným vstupem proběhne aplikace velmi rychle: interpret Perlu s aplikací
je již spuštěn a inicializace provedena. Poněkud náročnější než v předchozím
případě je předávání vstupních dat (Unix-domain socket). Fast-CGI aplikaci lze
spustit jako aplikaci statickou nebo dynamickou. Dynamická aplikace může běžet
ve více instancích: Podle "zájmu" o aplikaci (počet souběžných požadavků) jsou
nové instance vytvářeny, resp. ukončovány. To sice zvyšuje zátěž systému, avšak
na rozdíl od CGI je "životnost" instance větší než jeden požadavek. Statická
aplikace je spuštěna při startu HTTP serveru v jediné instanci a další už se
nespouští. Souběžné požadavky musí čekat ve frontě, až na ně přijde řada.
Varianta PHP
PHP je zdánlivě poměrně rychlé, pokud zpracovává malé množství dat. Je však
důležité si uvědomit, že při každém novém požadavku je skript načítán z disku a
provádí novou inicializaci. V této konkrétní aplikaci to není příliš znát,
protože data zůstanou v diskových bufferech a na disk se ve skutečnosti nemusí
přistupovat. Při zpracování vstupu většího rozsahu se zde PHP jeví jako velmi
pomalé. Oproti staršímu PHP verze 3 bylo zaznamenáno zhruba čtyřnásobné
zrychlení; přechod na novější verzi se tedy rozhodně vyplatí. Ani u PHP není
rozdíl mezi GET a POST. Varianta JS a JSP
Technologie JS a JSP mají mnoho společného. Srovnávají se vlastně dva servlety.
Jeden z nich je napsaný ručně; druhý je strojově vygenerovaný z JSP, je jinak
zkonstruovaný (potomkem jiné třídy,...). Tím je možné vysvětlit rozdílný výkon
na vstupu nulové délky. Zajímavé je, že s rostoucí velikostí zpracovávaných dat
roste potřebný čas pomaleji u JSP než u JS. To je pravděpodobně způsobeno tím,
že implicitní proud out, kterému se předávají výstupní data v JSP, je instance
objektu JspWriter a je bufferovaný. Data, která předáváme na výstup v JSP, se
tedy až do určité velikosti uchovávají v paměti a až později se najednou
předají objektu PrintWriter, který je skutečně pošle klientovi. V JS se pro
výstup dat používá přímo objekt PrintWriter, který bufferovaný není. Souběžné
požadavky jsou současně zpracovávány různými vlákny metody service(). Klient
tak dostane první vygenerovaná data poměrně brzy po odeslání požadavku, aniž by
se příliš zvyšovala zátěž systému, jak je tomu u CGI. U servletů a JSP je
efektivnější předávat data metodou POST než metodou GET. Shrnutí
Pokud píšeme webovou aplikaci s důrazem na výkon, měli bychom se rozhodně
vyhnout CGI skriptům. Potom máme na výběr z několika možností, konkrétní volba
záleží na okolnostech. PHP můžeme použít, jestliže klademe důraz na
jednoduchost programování a vytváříme pouze jednoduchou aplikaci, která nebude
zpracovávat velké množství dat ani provádět složitou inicializaci. Máme-li již
hotové CGI aplikace a chceme zvýšit jejich výkon s co nejmenší námahou, vhodnou
volbou je Fast-CGI. Převod CGI na Fast-CGI je totiž obvykle velmi snadný. Pokud
jsme ochotni do vývoje aplikací investovat více úsilí, nejlepší volbou je
nepochybně Java, zejména Java Server Pages. JSP jsou nejlepší alternativou,
když potřebujeme zpracovat velké množství dat (předáme je metodou POST).
Výsledná aplikace je přehledná (vkládání kódu do HTML), s rychlou odezvou
(multithreading) a snadno udržovatelná (JavaBeans).

Porovnání webových aplikačních rozhraní
Ę0 K101,427100,977Ę 2,454Ę 2,547Ę2,27ĘĘ2,377Ę 4,315Ę 4,546Ę 8,834ĘĘ8,345
Ę2 K126,161126,140Ę37,841Ę36,652Ę86,572Ę85,539Ę41,812Ę33,188Ę39,274Ę 31,698
Ę6 K178,702176,816107,886104,792255,558256,417117,028Ę91,424104,353Ę 84,244
10 K-227,553-173,606-423,515-150,098-143,845
Zajímavé odkazy
n Domovská stránka Fast-CGI http://www.FastCGI.com n Domovská stránka PHP
http://www.php.net, mirror na http://www.php.cz n Zend Optimizer
http://www.zend.com/zend/optimizer.php n Specifikace Java Servlet API
http://java.sun.com/products/servlet/ n Specifikace Java Server Pages
http://java.sun.com/products/jsp/ n Apache JServ Project
http://java.apache.org/jserv/ n Domovská stránka projektu GnuJSP
http://www.klomp.org/gnujsp/ n Apache HTTP Server Project
http://www.apache.org/httpd.html n JDK Port pro Linux
http://www.blackdown.org/java-linux.html
0 2779 / als









Komentáře
K tomuto článku není připojena žádná diskuze, nebo byla zakázána.