2014-08-29 6 views
31

Il loop eventi I/O Node.js è single o multithreaded?Ciclo eventi Node.js

Se sono presenti più processi di I/O, il nodo li inserisce in un ciclo di eventi esterno. Vengono elaborati in sequenza (prima i più veloci) o gestiscono il ciclo degli eventi per elaborarli contemporaneamente (... e in quali limiti)?

+0

[Ecco un video di YouTube] (https://www.youtube.com/watch?v=8aGhZQkoFbQ) da JSConf UE 2014 in cui Philip Roberts spiega i loop degli eventi. –

risposta

79

Event Loop

il ciclo degli eventi Node.js viene eseguito con un singolo thread, questo significa che il codice dell'applicazione che si scrive viene valutata su un singolo thread. Lo stesso Nodejs utilizza molti thread sottostanti tramite libuv, ma non devi mai occupartene quando scrivi codice nodejs.

Ogni chiamata che implica una chiamata I/O richiede la registrazione di una richiamata. Anche questa chiamata ritorna immediatamente, questo consente di eseguire più operazioni IO in parallelo senza utilizzare thread nel codice dell'applicazione. Non appena viene completata un'operazione di I/O, la richiamata verrà inserita nel ciclo degli eventi. Verrà eseguito non appena tutti gli altri callback che hanno premuto il ciclo degli eventi prima di essere eseguiti.

Esistono alcuni metodi per eseguire la manipolazione di base del modo in cui i callback vengono aggiunti al ciclo degli eventi. Di solito non dovresti averne bisogno, ma ogni tanto possono essere utili.

In nessun punto ci sarà mai due veri percorsi paralleli di esecuzione, così tutte le operazioni sono intrinsecamente sicuro filetto. Di solito ci saranno diversi percorsi di esecuzione simultanei asincroni che vengono gestiti dal ciclo degli eventi.

Read More about the event loop

Limitazioni

causa del ciclo di eventi, il nodo non deve iniziare un nuovo thread per ogni connessione TCP. Ciò consente al nodo di eseguire il servizio hundreds of thousands of requests contemporaneamente, a condizione che non si calcolino i primi 1000 numeri primi per ciascuna richiesta.

Ciò significa anche che è importante non eseguire operazioni a uso intensivo della CPU, poiché manterranno un blocco sul ciclo degli eventi e impediranno il proseguimento di altri percorsi di esecuzione asincroni. È inoltre importante non utilizzare la variante sync di tutti i metodi I/O, poiché manterranno anche un blocco sul ciclo degli eventi.

Se si desidera eseguire operazioni pesanti sulla CPU, è necessario delegare l'unità a un processo diverso in grado di eseguire l'operazione associata alla CPU in modo più efficiente oppure è possibile scriverla come node native add on.

Read more about use cases

Flow Control

Al fine di gestire la scrittura molti callback probabilmente si desidera utilizzare una libreria di flusso di controllo. Credo che questo è attualmente il più popolare libreria di base di callback:

Ho usato callback e hanno praticamente mi faceva impazzire, ho avuto molto meglio esperienza nell'utilizzo di promesse, Bluebird è molto popolare e veloce biblioteca promessa:

Ho trovato che questo è un argomento piuttosto delicato nella comunità dei nodi (callbacks vs promises), quindi con tutti i mezzi, usa quello che ritieni possa funzionare meglio per te personalmente. Una buona libreria di controllo del flusso dovrebbe anche darti tracce dello stack asincrono, questo è molto importante per il debug.

Il processo Node.js termina quando l'ultimo callback nel ciclo di eventi termina il suo percorso di esecuzione e non registra nessun altro callback.

Questa non è una spiegazione completa, vi consiglio di controllare questo thread, è abbastanza aggiornato:

How do I get started with Node.js

+0

@ WillemD'haeseleer per favore! Spiegami la prossima frase "Il ciclo degli eventi di Node.js gira sotto un singolo thread .. Lo stesso Nodejs usa molti thread sotto la libreria libuv". So come funziona js-loop nel browser, ma non capisco quale sia il ruolo del 'libuv' multi-thread. I thread –

+0

vengono utilizzati da libuv per tutti i tipi di materiale che richiedono operazioni associate alla CPU.Se vuoi capire meglio ti consiglio di leggere su libuv qui http://nikhilm.github.io/uvbook/threads.html, e qui: http://nikhilm.github.io/uvbook/basics.html –

+0

In che modo 'nodejs' è in grado di gestire connessioni concorrenti? Lo fa con un ritardo significativo? Ho sentito che potrebbe supportare decine di migliaia di connessioni simultanee, più di 'apache'. Potresti spiegare come tutto questo è possibile, a condizione che 'nodejs' gestisca/elabori le richieste' HTTP' su un singolo thread? –

18

Dalla risposta di Willem:

I Node.js il ciclo di eventi gira sotto un singolo thread. Ogni chiamata I/O richiede la registrazione di una richiamata. Anche ogni chiamata I/O restituisce immediatamente, ciò consente di eseguire più operazioni IO in parallelo senza utilizzare thread.

Vorrei iniziare a spiegare con questa citazione sopra, che è uno dei comuni equivoci del framework node js che sto vedendo ovunque.

Node.js non gestisce magicamente tutte quelle chiamate asincrone con un solo thread e continua a mantenere il thread sbloccato. Utilizza internamente il motore V8 di google e una libreria chiamata libuv (scritta in C++) che consente di delegare alcuni potenziali lavori asincroni ad altri thread worker (un po 'come un pool di thread in attesa che qualsiasi lavoro venga delegato dal thread del nodo master). Successivamente, quando i thread terminano la loro esecuzione, chiamano i loro callback ed è così che il ciclo degli eventi è consapevole del fatto che l'esecuzione di un thread di lavoro è stata completata.

Il punto principale e il vantaggio di nodejs è che non dovrai mai preoccuparti di quei thread interni e rimarranno lontani dal tuo codice !. Tutte le brutte cose di sincronizzazione che dovrebbero normalmente accadere in ambienti multi-thread saranno astratte dal framework nodejs e puoi lavorare felicemente sul tuo singolo thread (thread del nodo principale) in un ambiente più programmabile (pur beneficiando di tutti i miglioramenti delle prestazioni di più thread).

Qui di seguito è un buon posto se qualcuno è interessato: When is the thread pool used?

+1

Sto dicendo che il ciclo degli eventi funziona a thread singolo, non all'intero nodo. Ho aumentato la mia risposta per sottolineare che non è necessario trattare i thread nel codice dell'applicazione in modo specifico. Grazie per il feedback. –