ugrás a tartalomhoz

Miből lesz a… Node.js?

Bártházi András · 2012. Feb. 10. (P), 10.17

A Node.js az egyik legdinamikusabban fejlődő projekt manapság, jelenleg a második legnépszerűbb (legtöbbek által figyelt) kód a Githubon, de sokáig első volt. A projektet indító Ryan Dahl nemrégiben közzétett egy videót, melyben beszél a kezdetekről, s ebből az is kiderül, hogy hogyan született meg ez a remek kezdeményezés.

A Node.js nekem is a szívem csücske, nagyon sok „szerver oldali JavaScript” (az idézőjel azért, mert a Node azért ennél több) megoldást kipróbáltam korábban, de messze a Node a legjobb közöttük, pedig iszonyatosan egyszerű.

Íme Ryan videója:

Talán a legérdekesebb dolog a videóban – elég könnyen ott lehet előtte ragadni! :) –, hogy Ryan egy viszonylag kis dolgot szeretett volna megoldani: valós időben kijelezni, hogy egy HTML feltöltés hol tart éppen. Na, ebből lett a Node.

Egyébként kiderül az is, hogy matekot tanult az egyetemen, de unalmasnak találta, és lelépett Dél-Amerikába (Chilébe). Aztán hat hónapnyi munkát tett bele a projektbe, bekunyerálta magát a berlini JSConfra, és a többi már történelem. :)

Ryan egyébként most hagyta ott a projekt vezetését (egy kicsit kiégett – ha jól sejtem, akkor megunta hogy a munka legkreatívabb részén túl vannak, s most a hibajavításos favágás korszak jön), de marad a Node-ot befogadó Joyentnél dolgozni.

 
2

Volt pár válasz

Bártházi András · 2012. Feb. 10. (P), 11.48
Erre a cikkre volt jópár válasz, eléggé megmozgatta a közösséget. Talán itt a Weblaboron is volt róla társalgás... Számomra az a konklúzió, hogy mindenben meg lehet találni a rosszat.
3

Amikor elindítasz mondjuk egy

Hidvégi Gábor · 2012. Feb. 10. (P), 12.02
Amikor elindítasz mondjuk egy adatbáziskérést vagy fájlműveletet, az a Node-ban egy callback segítségével történik meg, erre mondják, hogy non-blocking. Ezzel csak az a baj, hogy a "blokkoló" programozási nyelvekben sem áll meg az élet, az operációs rendszer átadja a vezérlést egy másik processznek.

Ez a megközelítés a Node-ban egy erősen töredezett kódot eredményez, amit, ha át akarsz látni, különféle programozási technikákat kell használnod. Persze van lehetőséged közben más szálakon egyéb műveleteket végezni, de ez egyrészt az általános feldolgozási sebességet csökkenti (a thread-ek számával exponenciálisan), másrészt külön tudomány a párhuzamos adatfeldolgozás megvalósítása: mikor lehet, lehet-e egyáltalán csinálni ilyet, szemaforokat figyelni, hogy a másik szál befejezte-e már a futását stb.
4

Nem ez a baj

Bártházi András · 2012. Feb. 10. (P), 15.01
Sok egyéb miatt viszont jó ez a felállás. A thread-ek létrehozása "költséges", ami a memóriahasználatot és a létrehozás idejét illeti. Sokkal több szálat, sokkal kevesebb erőforrással tudsz kiszolgálni, kevesebb munkával. Egyébként a ma már legnépszerűbb nginx is hasonlóképpen működik, mint a Node, és emiatt a logika miatt lett népszerű.

Valamire ez a jó, valamire más, felesleges vitatkozni.
5

Annyira nem akarok

Hidvégi Gábor · 2012. Feb. 10. (P), 15.14
Annyira nem akarok vitatkozni, csak azok alapján, amit eddig láttam a Node-dal kapcsolatban, vannak fenntartásaim, és még nem tudtam eldönteni, hogy hol és mennyire van létjogosultsága. Emiatt kíváncsi vagyok mások véleményére.

A fenti cikknek van folytatása, ahol arról értekezik a szerző, hogy a processz-, vagy az eseményalapú megközelítés a hatékonyabb.
6

"If you do more I/O than CPU, use more threads."

dropout · 2012. Feb. 10. (P), 16.16
Szerintem számítás igényes feladatokat nem szerveren kéne/kell végeztetni, hanem inkább kliens oldalon. Legalábbis én mindig erre törekedtem. Számítás igényes feladatra gondolok itt például a képek, esetleg videók tömörítésére, képkivágására, vagy pl.: dokumentumok generálására (pdf, xls stb...), tehát a cikk szerzőjének érvelése a threaded megoldás mellett szerver oldalon számomra teljesen elfogadható.
7

Ez a kliens megbízhatóságán

Hidvégi Gábor · 2012. Feb. 10. (P), 16.24
Ez a kliens megbízhatóságán múlik.
8

Node.js 0.6

Poetro · 2012. Feb. 10. (P), 17.41
A 0.6 óta létezik a Node.js alatt cluster modul, amivel eleve annyi szálat indít az alkalmazásodnak, ahány mag van a gépben. Ekkor minden szál egy load balancing eljárással kapja a kéréseket.

Természetesen Node alatt is van lehetőség szálakat létrehozni (child_process.fork), ami szintén egy külön szálban fog futni, viszont itt (is) neked kell figyelned a megosztott erőforrásokra (adatbázis, fájlok stb.). És ezeket például PHP-ban elég nehéz megvalósítani hagyományos technikák alkalmazásával. Például nyitsz egy szálat (child_process.exec), ami legenerálja neked például a kisképeket mondjuk ImageMagick segítségével, majd amint ezzel végzett, akkor egy callback-ben folytathatod az alkalmazás futását, miközben az alkalmazásod már írogathat adatbázisba, másolhat / létrehozhat fájlokat stb.
9

thread vs. process

dyuri · 2012. Feb. 10. (P), 18.05
Szerintem nem szerencses keverni a szal (thread) es gyerek folyamat (child process) fogalmakat, mert nem ugyan az a ketto. (Abbol a szempontbol, hogy mind a szalak, mind a gyerek folyamatok tudnak parhuzamosan futni mas-mas processzoron, abbol a szempontbol hasonloak, de egyebkent vannak jelentos kulonbsegek.)
10

Igaz, elnézést attól, akit

Poetro · 2012. Feb. 10. (P), 18.12
Igaz, elnézést attól, akit megtévesztettem.
11

Még pár hónapja készítettem

Hidvégi Gábor · 2012. Feb. 13. (H), 11.41
Még pár hónapja készítettem egy egyszerű scriptet, amivel a node MySQL elérés teljesítményét szerettem volna lemérni. Valamelyik korábbi hozzászólásomban benne van a kód, úgy működik, hogy 50 lekérdezést egymás után hív meg (amikor megkaptuk az eredményt az egyikből, futtatjuk a következőt, a php is ugyanígy, szekvenciálisan működik), és a végén kiírja a futtatáshoz szükséges időt. Ezt a scriptet most kipróbáltam Linuxon is, korábban Windowson elég siralmas eredményt produkált.

Az eredmények:
php + mysqlnd (unix socket): átlag 56ms
node + mysql (tcp): átlag 350ms

Majd keresek olyan mysql kiterjesztést node-hoz, ami unix socketen keresztül kommunikál, megnézem, azzal hogyan muzsikál.
12

Párhuzamosítás

Hidvégi Gábor · 2012. Feb. 14. (K), 11.02
Elkészítettem a fenti scriptem módosított változatát, ami a következőképp működik: van körülbelül 50 lekérdezésem, amiben vettem azokat, amelyeket elvileg párhuzamosan le lehet futtatni, így tizenhat csoportra osztottam őket. Az egyes csoportokban lévő kéréseket egymás mellett indítom el, és egy számlálóval nézem, hogy mikor fejeződött be az adott csoport lekérdezése, és ha megvan, indítom a következő csoportot.

Az eredmények a következők:
párhuzamos lekérdezések futtatásával: átlag 332ms
soros lekérdezések futtatásával (eredeti script): 380ms (ma valamiért lassabb a gépem)

Ez körülbelül 13%-os gyorsulást jelent.
13

Lehetne ennek az

inf · 2012. Feb. 14. (K), 17.16
Lehetne ennek az optimalizálásnak külön menüpontot, kategóriát, vagy blog bejegyzés meg még sokmindent csinálni. :-) Szerintem nyugodtan írj egy új blog bejegyzést az eredményeidről, mert így csak elkallódik.
14

Igen, folyamatosan

Hidvégi Gábor · 2012. Feb. 14. (K), 17.31
Igen, folyamatosan gondolkozom ilyeneken, bár leginkább az érdekelne, hogy php-ban hogyan lehetne megoldani ugyanezt a problémát.