Forever: deployment Node.js aplikací

Adam Štrauch 9. 11. 2012

O Node.js je poslední dva roky slyšet čím dál víc. Jde o běhové prostředí JavaScriptu na straně serveru. To není zrovna populární kombinace, ale své využití si našla. Jak to u takovýchto technologií bývá, bez vlastního serveru u nás světu nic neukážete, takže se podíváme, jak Node.js na serveru nastavit..

Myšlenka JavaScriptu na straně serveru vypadá na první pohled strašidelně, protože JavaScript obsahuje spoustu konstrukcí, které ne každému jdou na ruku a navíc byl doposud až magicky spojen s webovými prohlížeči. V tomto článku ale nebudu rozebírat použitý jazyk. Důležité je, co vám může projekt Node.js nabídnout, a kromě jazyka známého v celé webové komunitě to je možná až ohromující výkon v paralelních I/O operacích.

Node.js je postaveno na enginu V8, který znáte z prohlížeče Google Chrome a Chromium. K němu autoři připojili několik modulů komunikujících asynchronně se světem. V praxi to vypadá tak, že vytvoření malého web serveru neznamená, že budete ve smyčce čekat, až se objeví nové spojení, ale importujete http modul, řeknete mu, že má poslouchat na localhostu a portu 8000 a registrujete na něj svou callback funkci. Váš kód jede dál a když pak přijde spojení od uživatele, Node.js zavolá vaši registrovanou funkci. Když se podíváte na společnosti, které už Node.js nasadily, jsou jejich zkušenosti vesměs kladné. Pokud Node.js nasadíte tam, kde se nejvíce hodí, a to na aplikace s velkým množstvím paralelních I/O operací, je zrychlení proti alternativním řešením až dechberoucí.

Například služba LinkedIn se rozhodla používat Node.js jako backend pro jejich mobilní aplikaci. Mnoho konkurenčních požadavků, to je oblast, kde Node.js vyniká a reálná čísla to jen potvrzují. To, co dříve běželo na Ruby On Rails na 15 serverech a 15 virtuálních serverech na každém z nich, dnes běží pouze na čtyřech virtuálních serverech a navíc to zvládne dvojnásobnou zátěž. Jako bonus se prý podařilo aplikaci vyvinout velmi rychle. Více o technických detailech najdete v článku na serveru venturebeat.com.

Na eBay zase řešili, jak sjednotit několik API pod jednotné API a tím snížili počet požadavků od klientů. To se podařilo, ale v porovnání s předchozím případem je nárůst výkonu menší – běžný počítač s Ubuntu prý zvládl 120 000 spojení najednou, ale další informace pro porovnání tohoto čísla k dispozici nejsou. Co si vývojáři pochvalují, jsou hlavně nízké nároky na paměť (2 kB na každé spojení), škálovatelnost a jednodušší monitorování. Více o jejich zkušenostech najdete na ebaytechblog.com.

Deployment Node.js aplikace

Na začátku jsem zmínil, že Node.js je běhové prostředí pro JavaScript, takže co se týká hostování aplikací napsaných v JavaScriptu, není potřeba nic speciálního. Node.js umí komunikovat se světem různými protokoly, ale pro potřeby webu se nejvíce hodí HTTP. Hostování Node.js se tedy neliší nějak od Pythonu nebo Ruby on Rails, stačí aplikaci spustit jako daemona a nechat ji naslouchat na lokálním portu, na který nasměrujete reverzní proxy, nejlépe Nginx, ale nevadí ani Apache či jiný web server s touto funkcionalitou.

HTTP není jedinou možností, jak spojit web server s aplikací. Node.js je totiž jen základní balík, na kterém staví mnoho dalších modulů, takže existují implementace SCGI nebo FastCGI, nicméně k těmto modulům přistupujte s opatrností, protože nejsou vyvíjeny společně s Node.js, ale třetími stranami.

Kromě samotného otevření aplikace světu je ještě potřeba se postarat o to, aby na serveru běžela, a když by náhodou spadla, tak aby se opět spustila. K tomu je možné použít třeba Supervisor, o kterém jsme psali začátkem tohoto roku. Jde o velmi univerzální nástroj schopný spouštět téměř cokoli. Jednou z dalších možností je projekt forever, který je napsaný v JavaScriptu a pro JavaScript. Jeho použití je jednodušší, ale nepostará se o spuštění skriptu po restartu serveru.

I tak se jedná o rozumnou možnost, kterou rozhodně stojí rozebrat. Z ovládání si může vzít příklad kdejaký podobný nástroj. Forever se snaží vše co nejvíce zautomatizovat. Začneme tím, že si forever nainstalujeme. Pokud ještě v systému Node.js nemáte, tak v novějších distribucích ho nainstalujete z balíčku nodejs. Určitě během instalace ještě přidejte program npm, což je správce balíčků pro Node.js, kterým také nainstalujeme forever:

# npm -g install forever 

Parametr -g znamená globální instalaci, takže forever bude dostupný všem uživatelům systému.

Abychom nový přírůstek do systému vyzkoušeli, potřebujeme nějaký krátký program, třeba jeden z „Hello Worldů“, kterých se po Node.js tutoriálech válí hromada, a uložíme ho do souboru hello_world.js.

var http = require('http');
http.createServer(function (req, res) {
      res.writeHead(200, {'Content-Type': 'text/plain'});
        res.end('Hello World\n');
}).listen(8080, '127.0.0.1');
console.log('Server running at http://127.0.0.1:8080/'); 

Po spuštění se nastartuje HTTP serveru, který na každý požadavek vrátí text „Hello World“. Server běží na adrese 127.0.0.1 a na portu 8080. HTTP server spustíme jednoduše přes node:

$ node hello_world.js
Server running at http://127.0.0.1:8080/ 

Pokud jsme s výsledkem spokojeni, můžete zkusit forever. Použití je velmi jednoduché, jak naznačuje nápověda:

usage: forever [action] [options] SCRIPT [script-options] 

Kde action může být start, stop, stopall, restart, restartall, list, logs a několik dalších. Z parametrů je důležitý hlavně -w, kterým lze forever říci, že když se skript změní, má se běžící instance zabít a nastartovat nová. Mezi další parametry patří třeba -l říkající kde má být soubor s logy, parametr -o je obdobou pro stdout a -e pro stderr. Další parametry jsou popsané v nápovědě -h.

Spuštění skriptu na pozadí se provede takto:

$ forever start hello_world.js info: Forever processing file: hello_world.js

Když skript běží, je možné si prohlédnout jeho logy. Příkaz logs zobrazí logy ke všem běžícím Node.js procesům a když se přidá pořadové číslo, objeví se i samotný log.

$ forever logs
info:   Logs for running Forever processes
data:        script         logfile
data:    [0] hello_world.js /home/cx/.forever/JVRf.log
$ forever logs 0
info:   Showing logs for hello_world.js
data:   Server running at http://127.0.0.1:8080/ 

Zastavení aplikace se dělá obdobným způsobem:

$ forever stop 0 

V tomto případě lze získat pořadové číslo pomocí příkazu list:

$ forever list
info:   Forever processes running
data:       uid  command script         forever pid logfile                    uptime
data:   [0] JVRf node    hello_world.js 528     529 /home/cx/.forever/JVRf.log 0:0:12:55.138 

Když skript běží, je potřeba na něj nasměrovat Apache, Nginx nebo jiný webový server. Je možné skript spustit i přímo na portu 80, ale v takovém případě musí běžet pod uživatelem root, což vyžaduje práci navíc, kterou už autoři web serverů udělali. Nginx se ve většině distribucí schovává ve stejnojmenném balíčku a jeho konfiguraci najdete v /etc/nginx/nginx.conf. U Apache to je složitější a je lepší se řídit dokumentací vaší distribuce, stejně jako u konfigurace, která je u Apache mnohem více „distrocentrická“ než u Nginx.

Pro Nginx konfigurace reverzní proxy na běžící HTTP server vypadá takto:

server {
        listen       [::]:80;
        server_name  domena.cz www.domena.cz;

        access_log /var/log/app1.log;
        error_log /var/log/app1-error.log;

        location / {
                proxy_pass         http://127.0.0.1:8080/;
        }
} 

Názvy jednotlivých direktiv jsou dostatečně výmluvné, takže přejdeme na Apache, kde je konfigurace velmi podobná:

NameVirtualHost *:80
<VirtualHost *:80>
        ServerName domena.cz
        ServerAlias www.domena.cz

        ErrorLog /var/log/app1-error.log
        CustomLog /var/log/app1.log combined
        LogLevel error

        <Proxy *>
            Order deny,allow
            Allow from all
        </Proxy>
        ProxyPass /  http://127.0.0.1:8080/
</VirtualHost> 

Konfigurace jak Apache, tak Nginxu jsou témata na celé knihy a není v silách jednoho článku popsat všechny možnosti. Uvedené příklady ale budou fungovat ve většině případů bez problémů. Pokud i tak narazíte na nějakou nejasnost, pravděpodobně najdete odpověď v dokumentaci.

widgety

Shrnutí

Za forever můžeme poděkovat lidem z projektu nodejitsu, což je hosting Node.js aplikací postavený na cloudové infrastruktuře. Hostování Node.js aplikací na vlastním stroji ať už virtuálním či fyzickém není o moc náročnější než hostování jakékoli jiné aplikace. Pokud jste zatím pracovali jen s PHP, které má modul do Apache, připadá vám deployment Node.js určitě o něco složitější, ale pokud tento postup pochopíte, nebudete mít problémy s projekty napsanými v dalších jazycích jako je Python, Ruby nebo třeba Perl.

Za zmínku ještě stojí projekt nodeenv. Je napsaný v Pythonu a umožňuje uzavřít prostředí Node.js do adresáře. Díky tomu můžete provozovat aplikace s různými požadavky na knihovny a jejich verze, aniž by se navzájem ovlivňovaly. Nodeenv si poradí i s instalací různých verzí Nodejs. Projekt je víceméně podobný projektu virtualenv, který dělá to samé pro Python.

Našli jste v článku chybu?
Vitalia.cz: Tradiční čínská medicína a rakovina

Tradiční čínská medicína a rakovina

Lupa.cz: Blíží se konec Wi-Fi sítí bez hesla?

Blíží se konec Wi-Fi sítí bez hesla?

Lupa.cz: Cimrman má hry na YouTube i vlastní doodle

Cimrman má hry na YouTube i vlastní doodle

Lupa.cz: Proč jsou firemní počítače pomalé?

Proč jsou firemní počítače pomalé?

120na80.cz: Pálení žáhy: která jídla ne a co nás uzdraví?

Pálení žáhy: která jídla ne a co nás uzdraví?

Podnikatel.cz: Byla finanční manažerka, teď cvičí jógu

Byla finanční manažerka, teď cvičí jógu

DigiZone.cz: Nova opět stahuje „milionáře“

Nova opět stahuje „milionáře“

Lupa.cz: Jak se prodává firma za miliardu?

Jak se prodává firma za miliardu?

Vitalia.cz: Fyzioterapeutka: Chůze naboso? Rozhodně ano!

Fyzioterapeutka: Chůze naboso? Rozhodně ano!

DigiZone.cz: Funbox 4K v DVB-T2 má ostrý provoz

Funbox 4K v DVB-T2 má ostrý provoz

Vitalia.cz: 5 chyb, které děláme při skladování potravin

5 chyb, které děláme při skladování potravin

Vitalia.cz: Jak Ondra o astma přišel

Jak Ondra o astma přišel

DigiZone.cz: Technisat připravuje trojici DAB

Technisat připravuje trojici DAB

Podnikatel.cz: Udělali jsme velkou chybu, napsal Čupr

Udělali jsme velkou chybu, napsal Čupr

Vitalia.cz: dTest odhalil ten nejlepší kečup

dTest odhalil ten nejlepší kečup

Vitalia.cz: Pryč se zastaralým stravováním ve školách

Pryč se zastaralým stravováním ve školách

Vitalia.cz: Test dětských svačinek: Tyhle ne!

Test dětských svačinek: Tyhle ne!

DigiZone.cz: Parlamentní listy: kde končí PR...

Parlamentní listy: kde končí PR...

Vitalia.cz: Tohle jsou nejlepší česká piva podle odborníků

Tohle jsou nejlepší česká piva podle odborníků

120na80.cz: Co je padesátkrát sladší než cukr?

Co je padesátkrát sladší než cukr?