[ Questo post è aggiornato al 2012-09-02 (più recente di quanto sopra). ]
Node.js è assolutamente scalabile su macchine multi-core.
Sì, Node.js è un thread per processo. Questa è una decisione di progettazione molto deliberata ed elimina la necessità di gestire la semantica di blocco. Se non sei d'accordo, probabilmente non ti rendi ancora conto di quanto sia follemente difficile eseguire il debug del codice multi-thread. Per una spiegazione più approfondita del modello di processo Node.js e perché funziona in questo modo (e perché non supporterà MAI più thread), leggi il mio altro post .
Quindi, come posso sfruttare la mia scatola a 16 core?
Due strade:
- Per attività di calcolo pesanti come la codifica delle immagini, Node.js può attivare processi figlio o inviare messaggi a processi di lavoro aggiuntivi. In questo progetto, avresti un thread che gestisce il flusso di eventi e N processi che svolgono compiti di calcolo pesanti e masticano le altre 15 CPU.
- Per ridimensionare il throughput su un servizio Web, è necessario eseguire più server Node.js su un box, uno per core e dividere il traffico delle richieste tra di loro. Ciò fornisce un'eccellente affinità con la CPU e ridimensionerà il throughput in modo quasi lineare con il conteggio dei core.
Ridimensionamento della velocità effettiva su un servizio Web
Poiché v6.0.X Node.js ha incluso il modulo cluster immediatamente, il che semplifica la configurazione di più nodi di lavoro che possono ascoltare su una singola porta. Si noti che questo NON è lo stesso del vecchio modulo "cluster" di learnboost disponibile tramite npm .
if (cluster.isMaster) {
// Fork workers.
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
} else {
http.Server(function(req, res) { ... }).listen(8000);
}
I lavoratori competeranno per accettare nuove connessioni e il processo meno caricato avrà più probabilità di vincere. Funziona abbastanza bene e può aumentare abbastanza bene la velocità su una scatola multi-core.
Se hai abbastanza carico per occuparti di più core, allora vorrai fare anche qualche altra cosa:
Esegui il tuo servizio Node.js dietro un proxy web come Nginx o Apache - qualcosa che può limitare la connessione (a meno che non desideri che le condizioni di sovraccarico riducano completamente la casella), riscrivi gli URL, offri contenuto statico e proxy altri servizi secondari.
Ricicla periodicamente i tuoi processi di lavoro. Per un processo di lunga durata, alla fine si sommerà anche una piccola perdita di memoria.
Raccolta / monitoraggio del registro di installazione
PS: C'è una discussione tra Aaron e Christopher nei commenti di un altro post (al momento della stesura di questo, è il primo post). Alcuni commenti al riguardo:
- Un modello di socket condiviso è molto conveniente per consentire a più processi di ascoltare su una singola porta e competere per accettare nuove connessioni. Concettualmente, potresti pensare ad Apache preforked che lo fa con l'importante avvertimento che ogni processo accetterà solo una singola connessione e poi morirà. La perdita di efficienza per Apache è nell'overhead del fork di nuovi processi e non ha nulla a che fare con le operazioni del socket.
- Per Node.js, avere N lavoratori in competizione su un singolo socket è una soluzione estremamente ragionevole. L'alternativa è impostare un front-end integrato come Nginx e disporre di quel traffico proxy per i singoli lavoratori, alternando i lavoratori per l'assegnazione di nuove connessioni. Le due soluzioni hanno caratteristiche prestazionali molto simili. E poiché, come ho già detto, probabilmente vorrai avere Nginx (o un'alternativa) in grado di supportare il tuo nodo in ogni caso, la scelta qui è davvero tra:
Porte condivise: nginx (port 80) --> Node_workers x N (sharing port 3000 w/ Cluster)
vs
Porte individuali: nginx (port 80) --> {Node_worker (port 3000), Node_worker (port 3001), Node_worker (port 3002), Node_worker (port 3003) ...}
Ci sono probabilmente alcuni vantaggi nell'impostazione delle singole porte (potenziale per avere meno accoppiamento tra processi, prendere decisioni più sofisticate sul bilanciamento del carico, ecc.), Ma è sicuramente più lavoro da impostare e il modulo cluster integrato è basso alternativa di complessità che funziona per la maggior parte delle persone.