\"/
\"/ \"/    

FastCGI: rychleji, lépe, bezpečněji

Jaromír Doleček, FI MU, ÚVT MU
Ročník VIII - číslo 2, prosinec 1997
Citace: J. Doleček. FastCGI: rychleji, lépe, bezpečněji. Zpravodaj ÚVT MU. ISSN 1212-0901, 1997, roč. VIII, č. 2, s. 7-9.
Tematické zařazení: Software obecně - principy, tvorba, Webové zdroje a technologie
 předchozí článek | následující článek 

Rozhraní CGI1 sloužilo dlouhou dobu jako univerzální nástroj pro generování dynamických dokumentů. Jeho podpora je dnes standardní součástí téměř každého www-serveru, protože se jedná o jednoduché a konzistentní prostředí. Pomocí programů využívajících standardu CGI (dále CGI-programů) jsou realizovány přístupy do databází, prohledávací stroje, vedeny seznamy přístupů na www stránky a zpracovávána uživatelská data zadaná pomocí formulářů. Návrh CGI neklade žádné požadavky na to, jak musí vypadat server či operační systém, který CGI-programy spouští, ani na to, v jakém konkrétním programovacím jazyce je CGI-program napsán. Programátor ani provozovatel www-serveru tedy nejsou omezeni ve svém výběru aplikačního prostředí.

V čem je problém?

Největší nevýhodou každého CGI-programu je to, že je při každém požadavku znovu spuštěn. Je to obdoba situace, kdy by si člověk na zobrazení každé jednotlivé www stránky musel znovu a znovu spouštět Netscape Navigátora. Spustit program a vytvořit tak nový proces je pro operační systém poměrně náročné a chvíli to trvá (u CGI-skriptů pravda ne tak dlouho jako spuštění prohlížeče, ale prodleva je znatelná).
Čas samotného spuštění CGI-programu však není jediný faktor zpomalující celkový výkon CGI. Složitější CGI-programy čtou často různé konfigurační soubory, přistupují do databází nebo vyhledávají informace v lokálním systému. CGI-program musí v takovém případě vždy znovu provést inicializaci, načíst konfigurační soubor, vytvořit spojení do databáze - a po zpracování požadavku zase beze stopy skončí a pracně získané informace jsou ztraceny. U CGI-programů napsaných v některém ze skriptovacích jazyků se přidává ještě čas inicializace vlastního interpretu. Server si s CGI-programem předává data pomocí systémových služeb (typicky přes rouru), což dále snižuje rychlost odezvy.

Snaha o urychlení zpracování požadavků vedla k vývoji interních serverových modulů: www-server obsahuje speciální sadu funkcí (API - Application Programming Interface - rozhraní pro programování aplikací), které moduly používají ke spolupráci se zbytkem serveru. Každý modul se stává součástí www-serveru, čímž rozšiřuje jeho možnosti. Každý "větší" www-server nyní podobné rozhraní obsahuje - Apache má Apache API, servery Netscape NSAPI, MS IIS ISAPI, jiné servery zase jiné.

Ačkoli se vlk nažral (už není nutno používat CGI, moduly na straně serveru jsou výrazně rychlejší, nemusí se pokaždé spouštět nový proces), koza nezůstala celá.

Bylo by vhodné, aby existovalo něco mezi, něco, co by spojovalo výhody CGI (nezávislost na serveru a programovacím jazyku, oddělení od kódu www-serveru) s rychlostí serverových modulů. Takové řešení již existuje - jeho jméno je FastCGI2 a bylo vyvinuto firmou Open Market, Inc.

CGI s tryskovým motorem

Myšlenka je velmi jednoduchá - FastCGI-program není spouštěn při každém požadavku vždy znovu, ale spustí se jako samostatná aplikace bez návaznosti na jakýkoli konkrétní požadavek. Čeká pak, dokud není třeba jeho služeb. Jakmile takový okamžik nastane, www-server a FastCGI-aplikace spolu navážou spojení a předají si data.

Vzhledem k tomu, že FastCGI-program může počítat s tím, že neskončí hned po dokončení zpracování dat, bylo možno rozdělit vlastní funkci programu na několik podfází tak, aby se zbytečně opakovaně neprováděly akce, které je možno provést pouze jednou. Může si také například udržovat cache různých dat, používaných při vyřizování požadavku, čímž dále urychlí svou práci.

Zatímco typický CGI-program provede víceméně v náhodném sledu čtení vstupních dat, vnitřní inicializaci a výstup (a často končí kdekoli během svého běhu), FastCGI-program je výhodné napsat lépe. Typický FastCGI-program má následující schéma:

Je tedy velmi jednoduché přepsat CGI-aplikaci jako FastCGI - stačí najít to, co je možné provést jen jednou, přesunout to na začátek programu a zbytek umístit do cyklu. Jako podmínka cyklu se použije volání funkce, která provádí vlastní čekání na data a inicializaci proměnných. Malý příklad v jazyce C - pokud by původní program vypadal nějak takto:

     void main()
{
    init_once();
    handle_request();
}

pak po přepsání do FastCGI by vypadal takto:

     void main()
{
    init_once();
    while(FCGI_Accept() >= 0) {
       handle_request();
    }
}

Ke správné funkci FastCGI-programu je nutno mít také knihovnu FastCGI funkcí, v níž je implementována mimo jiné i výše použitá funkce FCGI_Accept().
Někdy je nutné provést další úpravy v programu, protože nepříjemným zvykem CGI-programů je kromě jiného i skončit, kdykoli se jim zachce - kód programu tedy musí být přepsán tak, aby běh programu skončil pokaždé zpět v hlavním cyklu. CGI-programy také někdy nemají zcela korektně vyřešenu alokaci/dealokaci systémových prostředků (paměť, ovladače souborů). U CGI to vcelku nevadí (program stejně rychle skončí a operační systém prostředky držené procesem obvykle uvolní), ale u FastCGI už to problém je. Nejjednodušší je, aby v takovém případě FastCGI-program zpracoval jen určitý počet požadavků a poté skončil - což sice není opravdové řešení, ale je tak možné okamžitě využít výhod FastCGI a program může být opraven později.

FastCGI-program se zbavuje své závislosti na konkrétním www-serveru, což mimo jiné znamená, že není tak obtížné přejít k jinému, pokud ten starý z jakýchkoli důvodů nevyhovuje. Rychlost odezvy FastCGI-programů je přitom velmi blízká rychlosti při použití interních modulů. Jediná daň, kterou za svou univerzalitu FastCGI-programy platí, je zpomalení zaviněné komunikací mezi serverem a FastCGI-programem. Zatímco u interního modulu není třeba nijak předávat data do a z modulu (vše se děje uvnitř serveru), FastCGI si se serverem data vyměňovat musí. Používá k tomu obvykle systémové služby, implementace pro Apache/Unix například používá Unix domain socket. V praxi však toto zpomalení není znatelné, také proto, že kvantum předaných dat se obvykle pohybuje pouze v jednotkách až desítkách kilobytů.

Další vlastností, kterou si FastCGI propůjčilo od CGI, je faktická nezávislost na jazyku, ve kterém lze FastCGI-program napsat. V době psaní tohoto článku existovala podpora FastCGI pro jazyky C, Python, Perl a Tcl. Interní implementace FastCGI knihovny (obsahující funkce nutné k běhu programu jako FastCGI) používá vlastní stdio rutiny, takže některé interprety je nutno upravit, aby v nich bylo možno psát FastCGI-aplikace. Po úpravě fungují jak "obyčejné" skripty, tak i FastCGI. Taková úprava je nutná pro Perl a Tcl.

Pomocí FastCGI lze psát distribuované aplikace, kdy na jednom stroji aplikace skutečně běží a na jiném (popř. jiných) se používají její výsledky.

FastCGI samozřejmě nefunguje na serveru samo od sebe. Server si musí umět vyměňovat s FastCGI-programem data a musí umět program také znovu spustit, pokud z jakýchkoli důvodů skončí. Typicky je podpora pro FastCGI implementována jako modul s použitím API příslušného serveru. Jakmile je server připraven obsluhovat FastCGI-programy, lze je na něm používat bez dalších omezení.
V současné době existují moduly pro podporu FastCGI pro Apache 1.2.X, Netscape Commerce a Enterprise (podpora napsána firmou North American Media Express), Stronghold Secure Webserver, NCSA httpd a Secure WebServer firmy Open Market, Inc. Asi nic nebrání napsání podobné podpory i pro MS IIS, nicméně nic takového zatím není veřejně k dispozici. Kterýkoli www-server podporující standard CGI však může přistupovat k FastCGI-aplikacím pomocí CGI-programu cgi-fcgi.

Jak to mohu začít používat?

Aby bylo možno začít programovat FastCGI-aplikace, je nutno stáhnout ze serveru firmy Open Market FastCGI Developer Kit a zkompilovat příslušnou knihovnu pro pozdější použití; je-li nutno, pak také upravit a znovu zkompilovat používaný interpret a přečíst si dokumentaci. Toť vše ;-)

Je obvykle velmi jednoduché přepsat CGI do FastCGI (rozhraní bylo speciálně navrženo tak, aby tomu tak bylo a záměr se vydařil). FastCGI je freeware (i přesto, že je vyvíjen komerční firmou), a potenciální programátor se tedy nemusí obávat, že by po něm byly vymáhány poplatky za používání. Navíc je k dispozici poměrně dobrá dokumentace (nehledě na množství již existujících FastCGI-programů), takže není problém přijít na to, jak je třeba FastCGI-program napsat, aby "to běželo". Je zachována velmi silná vazba s CGI, takže je možné psát programy tak, aby fungovaly jako CGI i jako FastCGI.

Není problém najít kombinaci server-jazyk, která vyhovuje snad každému. Jazyky nejčastěji používané pro programování CGI-skriptů mají podporu pro FastCGI. Pro nejčastěji používané www-servery (Apache, Netscape) existuje podpora FastCGI pomocí interních modulů, na ostatních lze použít CGI-skript cgi-fcgi. Programovat FastCGI-aplikace s komfortem mohou ti movitější také pomocí vývojového prostředí Saphire/Web firmy Bluestone Software, Inc.

Další informace k FastCGI je možno nalézt na adrese http://www.fastcgi.com/. Informace týkající se FastCGI na serverech Netscape lze najít na http://fastserv.name.net/. Informace o firmě Bluestone Software, Inc. lze najít na její domácí stránce http://www.bluestone.com/.

setting
1 Common Gateway Interface - rozhraní pro komunikaci mezi externími programy a informačními - např. www - servery; bližší informace viz seriál CGI a dynamické www-dokumenty, který začal v minulém čísle Zpravodaje.
... zpět do textu
2 Název článku parafrázuje olympijské citius, altius, fortius.
... zpět do textu
Zpět na začátek
ÚVT MU, poslední změna 14.11.2011