2012-11-12 19 views
9

Diciamo che sto costruendo un sito Web a 3 livelli, con Mongo DB sul back-end e qualche javascript davvero leggero nel browser (diciamo solo la convalida sui moduli, forse un paio di controlli fantasiosi che attivano alcune richieste AJAX).Node.js dovrebbe essere utilizzato per l'elaborazione intensiva?

Ho bisogno di scegliere una tecnologia per il livello 'medio' (potremmo segmentarlo in sottolivelli ma quel dettaglio non è l'obiettivo qui, solo la scelta tecnologica complessiva), dove voglio crimpare alcuni dati grezzi uscendo dal DB, e renderlo in qualche HTML che spingo al browser. Un'architettura web thin client abbastanza tipica.

La mia scelta sicura sarebbe quella di implementare questo livello intermedio in Java, usando alcune librerie come Jongo per parlare con il Mongo DB e forse Jackson per il marshall/unmaresciallo JSON per parlare con i miei fantasiosi controlli quando fanno richieste AJAX. E qualche framework di template Java per rendere il mio HTML sul server.

Tuttavia, sono davvero incuriosito dall'idea di buttare tutto questo fuori dalla finestra e usando Node.js per questo livello intermedio, per i seguenti motivi:

  • io come JavaScript (le parti buone), e diciamo che per la logica di business di questa applicazione sarebbe più espressiva di Java.

  • È javascript ovunque. Non è necessario passare da una lingua all'altra e, in effetti, all'OO e ai paradigmi funzionali, quando si lavora in qualsiasi punto dello stack. Non ci sono tubazioni di traduzione tra i livelli, JSON è supportato nativamente ovunque.

  • Posso riutilizzare la logica di convalida sul client e sul server.

  • Se in futuro deciderò di eseguire il rendering HTML lato client nel browser, posso riutilizzare i modelli esistenti con qualcosa come Backbone con uno sforzo minimo di refactoring/retesting.

Se siete a questo punto e come Nodo, tutto quanto sopra sembrerà ovvio. Quindi dovrei scegliere il nodo giusto?

MA ... questo è il posto in cui cade per me: come tutti sappiamo, il nodo si basa su un modello di server Web I/O asincratico a thread singolo. Questo è ottimo per la mia scalabilità e le prestazioni in termini di richieste di assistenza per i dati, ma per quanto riguarda la mia logica aziendale? E il rendering del mio modello? Questa roba non causerà un enorme collo di bottiglia per tutte le richieste sul singolo thread?

soluzioni

Due evidenti vengono in mente, ma nessuno dei due si siede a destra:

  1. Mantenere la logica di business 'blocco' in là e basta usare un gruppo di istanze di Node e un bilanciatore di carico, alle richieste di servizio in vero parallelo. Ok bene, quindi perché non è Node solo multi-threaded in primo luogo? O è sempre stata questa l'idea, Keep It Simple Stupid ed evitare la possibilità di complessità multi-thread nel caso base, facendo in modo che il programmatore esegua il lavoro di installazione extra su questo se si desidera potenza di elaborazione multi-core?

  2. Mantenere una singola istanza di nodo e mantenerla non bloccante richiamando solo alcune implementazioni java della mia logica aziendale in esecuzione su un altro server di app muti-threaded. Ok, questa opzione annulla completamente ogni professionista che ho elencato sull'uso del Nodo (in realtà aggiunge complessità solo usando Java), oltre ai possibili guadagni in termini di prestazioni e scalabilità per le richieste CRUD al DB.

che mi porta infine al punto della mia domanda - mi sto perdendo un enorme pezzo importante del puzzle Nodo, ho appena ricevuto la mia fatti completamente sbagliato, o è il nodo semplicemente inadatto per macinare la logica di business sul server? In altre parole, il nodo è utile solo per sedersi su un database e servire molte richieste CRUD in un modo più performante e scalabile rispetto ad altre implementazioni che bloccano l'I/O? E devi fare tutta la tua logica di business in un qualche livello inferiore, o anche lato client, per mantenere qualsiasi ragionevole livello di prestazioni e scalabilità?

Considerando tutto il brusio di Node, avrei preferito sperare in un numero maggiore di tavoli. Mi piacerebbe essere convinto altrimenti!

+0

La ragione per cui il nodo è a thread singolo è JavaScript in tutte le sue attuali incarnazioni (non pianificate o incarnazioni "edge") è a thread singolo. Ci sono alcune eccezioni a questa regola, come i webworker nel client, ma anche in questo caso il tuo modello di threading è diverso da quello a cui potresti essere abituato in altre lingue. – Matt

+0

Buon punto, non intendevo veramente multi-thread, perché i thread possono condividere dati, intendevo qualcosa di simile ai webworker - solo un modo per le richieste di essere assistite in parallelo, senza la conoscenza l'una dell'altra, da la scatola. Questo può ovviamente essere ottenuto raggruppando i server dei nodi: la mia domanda è: qual è il caso d'uso in cui non si vorrebbe farlo? Quale reale utilizzo pratico ha un server Web a nodo singolo? – davnicwil

risposta

7

In un dato sistema di voi ha N CPU disponibili (1-64, o qualsiasi altra cosa N capita di essere). In qualsiasi applicazione a uso intensivo della CPU, si sarà bloccati con un throughput di cpus N. Non c'è un modo magico per risolverlo aggiungendo più di N discussioni/processi/qualsiasi altra cosa. O il tuo codice deve essere più efficiente o hai bisogno di più CPU. Più discussioni non aiuteranno.

Uno degli aspetti poco apprezzati delle prestazioni con più CPU è che se è necessario eseguire operazioni intensive della CPU allo N + 1, il throughput per CPU diminuisce notevolmente. Un processo ad alta intensità di CPU tende ad aggrapparsi a quella CPU per un tempo molto lungo prima di abbandonarlo, facendo morire di fame le altre attività. Nella maggior parte dei casi, sta bloccando l'I/O e il concomitante passaggio di attività che rende il multitasking del sistema operativo moderno altrettanto efficace. Se molti dei nostri compiti quotidiani fossero legati alla CPU, scopriremmo che avevamo bisogno di molte più CPU nelle nostre macchine rispetto a quelle attuali.

La cosa bella che Node.js offre al server in termini di efficienza è un uso approfondito di ogni thread. Idealmente, si finisce con un minore cambio di attività. Questa non è una vittoria enorme, ma avendo N discussioni movimentazione N * C connessioni asincrono sta per avere un vantaggio di prestazioni rispetto N * C blocco thread in esecuzione sullo stesso numero di CPU. Ma la linea di fondo sulle CPU rimane la stessa: se si ha più del valore di N del lavoro effettivo della CPU, sentirai un po 'di dolore.

L'ultima volta che ho guardato all'API Node.js c'era un modo per avviare un server con un listener più un thread di lavoro per CPU. Se riesci a farlo, sarei propenso ad andare con Node.js a condizione che vengano soddisfatte alcune limitazioni:

  • L'approccio Javascript-ovunque ti offre un po 'di semplicità. Per qualcosa di complicato, sarei preoccupato dello stile di programmazione asincrono che rende le cose più difficili invece che più semplici.
  • L'elaborazione del modello e altre attività a uso intensivo della CPU non sono significativamente più lente in Node.js delle altre opzioni di lingua/piattaforma.
  • I driver del database sono affidabili.

C'è un aspetto negativo che posso vedere:

  • se un thread si blocca, si perdono tutte le connessioni di essere serviti da quel thread.

Infine, prova a ricordare che il tempo del programmatore è generalmente più costoso dei server o della larghezza di banda.

+0

Ottima risposta. Quindi penso che in realtà si stia usando meno thread (o forse anche un singolo thread) per ascoltare e servire le richieste, eliminando il blocco su I/O. Questo ha molto senso. Grazie per aver sottolineato il potenziale utilizzo dei thread di lavoro: questo è esattamente ciò di cui stavo parlando, ovvero essere in grado di eseguire il farm in un pool di thread di lavoro quando è necessario eseguire alcune elaborazioni reali, ad esempio su una richiamata da una lettura DB, mentre mantenendo la filettatura del listener della richiesta. Ovviamente hai ragione che qualsiasi lavoro svolto è in definitiva vincolato dalla CPU del server e dalla velocità di V8 :-) – davnicwil

Problemi correlati