Programmering

Hva er Node.js? JavaScript-kjøretid forklart

Skalerbarhet, ventetid og gjennomstrømning er viktige ytelsesindikatorer for webservere. Det er ikke lett å holde ventetiden lav og gjennomstrømningen høy mens du skalerer opp og ut. Node.js er et JavaScript-kjøretidsmiljø som oppnår lav ventetid og høy gjennomstrømning ved å ta en "ikke-blokkerende" tilnærming til serveringsforespørsler. Med andre ord kaster Node.js bort tid eller ressurser på å vente på at I / O-forespørsler skal returneres.

I den tradisjonelle tilnærmingen til å lage webservere, for hver innkommende forespørsel eller tilkobling serveren gyter en ny tråd for henrettelse eller gafler en ny prosess å håndtere forespørselen og sende et svar. Konseptuelt er dette veldig fornuftig, men i praksis medfører det mye overhead.

Mens du gyter tråder medfører mindre minne og CPU-overhead enn forking prosesser, det kan fortsatt være ineffektivt. Tilstedeværelsen av et stort antall tråder kan føre til at et tungt belastet system bruker dyrebare sykluser på trådplanlegging og kontekstbytte, noe som gir latens og setter grenser for skalerbarhet og gjennomstrømning.

Node.js tar en annen tilnærming. Den kjører en enkelttrådet hendelsessløyfe som er registrert i systemet for å håndtere tilkoblinger, og hver nye forbindelse forårsaker JavaScript tilbakeringingsfunksjon gi sparken. Tilbakeringingsfunksjonen kan håndtere forespørsler med ikke-blokkerende I / O-samtaler, og kan om nødvendig gyte tråder fra et basseng for å utføre blokkering eller CPU-intensive operasjoner og for å laste balanse over CPU-kjerner. Nodeens tilnærming til skalering med tilbakeringingsfunksjoner krever mindre minne for å håndtere flere tilkoblinger enn de fleste konkurransedyktige arkitekturer som skalerer med tråder, inkludert Apache HTTP Server, de forskjellige Java-applikasjonsserverne, IIS og ASP.NET og Ruby on Rails.

Node.js viser seg å være ganske nyttig for stasjonære applikasjoner i tillegg til servere. Vær også oppmerksom på at Node-applikasjoner ikke er begrenset til ren JavaScript. Du kan bruke hvilket som helst språk som sendes til JavaScript, for eksempel TypeScript og CoffeeScript. Node.js inneholder Google Chrome V8 JavaScript-motoren, som støtter ECMAScript 2015 (ES6) -syntaks uten behov for en ES6-til-ES5-sender som Babel.

Mye av Node-verktøyet kommer fra det store pakkebiblioteket, som er tilgjengelig fra npm kommando. NPM, Node-pakkebehandling, er en del av standard Node.js-installasjonen, selv om den har sitt eget nettsted.

Noe JavaScript-historie

I 1995 opprettet Brendan Eich, som da var entreprenør til Netscape, JavaScript-språket for å kjøre i nettlesere — på 10 dager, slik historien går. JavaScript var opprinnelig ment for å aktivere animasjoner og andre manipulasjoner av nettleserdokumentobjektmodellen (DOM). En versjon av JavaScript for Netscape Enterprise Server ble introdusert like etterpå.

Navnet JavaScript ble valgt for markedsføringsformål, da Suns Java-språk var mye hypet på den tiden. Faktisk var JavaScript-språket faktisk hovedsakelig basert på skjema- og selvspråkene, med overfladisk Java-lignende semantikk.

I utgangspunktet avviste mange programmerere JavaScript som ubrukelig for “ekte arbeid” fordi tolken kjørte en størrelsesorden saktere enn kompilerte språk. Det endret seg da flere forskningsinnsatser med sikte på å gjøre JavaScript raskere begynte å bære frukt. Mest fremtredende kan open source Google Chrome V8 JavaScript-motoren, som gjør just-in-time-kompilering, inlining og dynamisk kodeoptimalisering, faktisk overgå C ++ - koden for noen belastninger, og overgår Python for de fleste brukssaker.

Den JavaScript-baserte Node.js-plattformen ble introdusert i 2009 av Ryan Dahl, for Linux og MacOS, som et mer skalerbart alternativ til Apache HTTP Server. NPM, skrevet av Isaac Schlueter, ble lansert i 2010. En opprinnelig Windows-versjon av Node.js debuterte i 2011.

Joyent eide, styrte og støttet utviklingsarbeidet Node.js i mange år. I 2015 ble Node.js-prosjektet overlevert til Node.js Foundation, og ble styrt av stiftelsens tekniske styringskomité. Node.js ble også omfavnet som et Linux Foundation Collaborative Project. I 2019 slo Node.js Foundation og JS Foundation seg sammen for å danne OpenJS Foundation.

Grunnleggende Node.js-arkitektur

På høyt nivå kombinerer Node.js Google V8 JavaScript-motoren, en enkelt-trådet ikke-blokkerende hendelsessløyfe og et lavt nivå I / O API. Den strippede eksempelkoden vist nedenfor illustrerer det grunnleggende HTTP-servermønsteret ved hjelp av ES6-pilfunksjoner (anonyme Lambda-funksjoner deklarert ved hjelp av fettpiloperatøren, =>) for tilbakeringingene.

Begynnelsen på koden laster inn HTTP-modulen, setter serveren vertsnavn variabel til lokal vert (127.0.0.1), og stiller inn havn variabel til 3000. Deretter oppretter den en server og en tilbakeringingsfunksjon, i dette tilfellet en fettpilfunksjon som alltid returnerer det samme svaret på enhver forespørsel: statusKode 200 (suksess), innholdstype ren tekst og et tekstsvar på ”Hello World \ n”. Til slutt forteller den serveren å lytte på lokal vert port 3000 (via en stikkontakt) og definerer en tilbakeringing for å skrive ut en loggmelding på konsollen når serveren har begynt å lytte. Hvis du kjører denne koden i en terminal eller konsoll ved hjelp av node kommandoen og bla deretter til localhost: 3000 ved hjelp av en hvilken som helst nettleser på samme maskin, vil du se "Hello World" i nettleseren din. For å stoppe serveren, trykk Control-C i terminalvinduet.

Legg merke til at alle anrop i dette eksemplet er asynkrone og ikke-blokkerende. Tilbakeringingsfunksjonene påkalles som svar på hendelser. De createServer tilbakeringing håndterer en klientforespørselshendelse og returnerer et svar. De lytte tilbakeringing håndterer lytter begivenhet.

Node.js-biblioteket

Som du kan se på venstre side, figuren nedenfor, har Node.js et stort utvalg av funksjonalitet i biblioteket. HTTP-modulen vi brukte i eksempelkoden tidligere inneholder både klient- og serverklasser, som du kan se på høyre side av figuren. HTTPS-serverfunksjonaliteten som bruker TLS eller SSL, lever i en egen modul.

Et iboende problem med en enkelt-gjenget hendelsessløyfe er mangel på vertikal skalering, siden hendelsesslyngetråden bare vil bruke en enkelt CPU-kjerne. I mellomtiden utsetter moderne CPU-sjetonger ofte åtte eller flere kjerner, og moderne serverstativ har ofte flere CPU-sjetonger. En applikasjon med en tråd vil ikke dra full nytte av 24-pluss-kjernene i et robust serverstativ.

Du kan fikse det, selv om det tar litt ekstra programmering. Til å begynne med kan Node.js gyte barneprosesser og vedlikeholde rør mellom foreldrene og barna, på samme måte som systemet popen (3) samtale fungerer, ved hjelp av child_process.spawn () og relaterte metoder.

Klyngemodulen er enda mer interessant enn den underordnede prosessmodulen for å opprette skalerbare servere. De cluster.fork () metoden gyter arbeidsprosesser som deler foreldrenes serverporter, ved hjelp av child_process.spawn () under dekslene. Klyngemasteren distribuerer innkommende forbindelser mellom sine arbeidere ved å bruke en round-robin-algoritme som er sensitiv for arbeidsprosessbelastninger.

Merk at Node.js ikke gir rutinglogikk. Hvis du vil opprettholde tilstanden på tvers av tilkoblinger i en klynge, må du beholde økt- og påloggingsobjektene dine et annet sted enn RAM.

Node.js-pakkeøkosystemet

NPM-registeret er vert for mer enn 1,2 millioner pakker med gratis, gjenbrukbar Node.js-kode, noe som gjør det til det største programvareregisteret i verden. Merk at de fleste NPM pakker (i hovedsak mapper eller NPM-registerelementer som inneholder et program beskrevet av en package.json-fil) inneholder flere moduler (programmer du laster med krever uttalelser). Det er lett å forveksle de to begrepene, men i denne sammenheng har de spesifikke betydninger og bør ikke byttes ut.

NPM kan administrere pakker som er lokale avhengigheter av et bestemt prosjekt, samt globalt installerte JavaScript-verktøy. Når den brukes som en avhengighetsleder for et lokalt prosjekt, kan NPM installere, i en kommando, alle avhengighetene til et prosjekt gjennom filen package.json. Når det brukes til globale installasjoner, krever NPM ofte systemrettigheter (sudo).

Det gjør du ikke ha å bruke NPM-kommandolinjen for å få tilgang til det offentlige NPM-registeret. Andre pakkeforvaltere som Facebook’s Garn tilbyr alternative opplevelser på klientsiden. Du kan også søke og bla gjennom pakker ved hjelp av NPM-nettstedet.

Hvorfor vil du bruke en NPM-pakke? I mange tilfeller er å installere en pakke via NPM-kommandolinjen den raskeste og mest praktiske for å få den siste stabile versjonen av en modul som kjører i miljøet ditt, og er vanligvis mindre arbeid enn å klone kildedepotet og bygge en installasjon fra depotet. Hvis du ikke vil ha den nyeste versjonen, kan du spesifisere et versjonsnummer til NPM, noe som er spesielt nyttig når en pakke er avhengig av en annen pakke og kan bryte med en nyere versjon av avhengigheten.

Eksempelvis gir Express-rammeverket, et minimalt og fleksibelt rammeverk for Node.js-applikasjoner, et robust sett med funksjoner for å bygge enkeltsidige og flersidige og hybrid-webapplikasjoner. Mens det enkelt klonbare Expresscode-depotet ligger på //github.com/expressjs/express og Express-dokumentasjonen er på //expressjs.com/, er en rask måte å begynne å bruke Express å installere den i en allerede initialisert lokal arbeidsutvikling katalog med npm kommando, for eksempel:

$ npm install express - lagre

De -lagre alternativet, som faktisk er slått på som standard i NPM 5.0 og senere, forteller pakkeadministratoren å legge til Express-modulen i avhengighetslisten i package.json-filen etter installasjon.

En annen rask måte å begynne å bruke Express på er å installere den kjørbare filen generatoruttrykke (1) globalt, og bruk den deretter til å opprette applikasjonen lokalt i en ny arbeidsmappe:

$ npm installer -g ekspressgenerator @ 4

$ express / tmp / foo && cd / tmp / foo

Når det er oppnådd, kan du bruke NPM til å installere alle nødvendige avhengigheter og starte serveren, basert på innholdet i package.json-filen opprettet av generatoren:

$ npm installasjon

$ npm start

Det er vanskelig å plukke høydepunkter ut av de millioner pluss pakkene i NPM, men noen få kategorier skiller seg ut. Express er det eldste og mest fremtredende eksemplet på Node.js-rammeverk. En annen stor kategori i NPM-depotet er JavaScript-utviklingsverktøy, inkludert browserify, en modulbundler; bower, nettleserens pakkeforvalter; grunt, JavaScript-oppgaveløperen; og gulp, streaming build-systemet. Endelig er en viktig kategori for bedriftens Node.js-utviklere databaseklienter, hvorav det er mer enn 8000, inkludert populære moduler som redis, mangoose, firebase og pg, PostgreSQL-klienten.

For å oppsummere er Node.js et JavaScript-runtime-miljø på tvers av plattformer for servere og applikasjoner. Den er bygget på en enkelt tråd, ikke-blokkerende hendelsessløyfe, Google Chrome V8 JavaScript-motoren og et lavt nivå I / O API. Ulike teknikker, inkludert klyngemodulen, lar Node.js-apper skaleres utover en enkelt CPU-kjerne. Utover kjernefunksjonaliteten har Node.js inspirert et økosystem med mer enn en million pakker som er registrert og versjonert i NPM-depotet og kan installeres ved hjelp av NPM-kommandolinjen eller et alternativ som Garn.