Realizzare portali con Node.js

Node.js è il framework per eccellenza utilizzato dalle grosse aziende Americane: LinkedIn, NASA, Twitter, Medium, Groupon, Walmart, GoDaddy,… perché fornisce ottime prestazioni e costi relativamente bassi, il che lo rende molto economico anche perché può essere sviluppato da sviluppatori full-stack, mentre gli altri framework hanno bisogno di developer front-end e back-end.

Comm.it realizza portali e-commerce con il Framework NodeJS

Perché realizzare il portale con Node.js?

Node.js è un framework scritto in Javascript che è il linguaggio di programmazione usato nel front-end per realizzare il layout delle pagine Web, ma in questo caso è usato nel back-end dove comunica con le richieste dei browser o delle App mobili traducendo queste comunicazioni in linguaggio comprensibile per il DataBase, ed ottenere così dati: modificati, cancellati o nuovi.

 

Si usa node.Js per creare gli endpoint che hanno delle API che sono dei servizi usati per fornire dati o cancellarli oppure aggiungerli.

 

E’ possibile interagire con gli endpoint e comunicando con il database tramite, in genere, il front-end, che è un altro framework per fare la single-page application (SPA) oppure con le app dei dispositivi mobili.

 

La SPA è un’architettura semplice da realizzare e veloce nel fornire dati e layout ai browser senza il bisogno di fare il reload della pagina che è un modo vecchio e lento per fornire le pagine al browser o alle app mobili.

 

Queste richieste agli endpoint Node.js le interpreta e risponde in modo veloce più dei suoi concorrenti: Laravel, Spring, Django,…

Comm.it themes responsive con Node.JS

Scrivere API in Node.JS lo rende il Framework più conveniente

Come afferma la cosiddetta legge di Atwood: “Qualsiasi applicazione che può essere scritta in JavaScript verrà eventualmente scritta in JavaScript”. L’uso di JS dal back-end al front-end è un fattore di ottimizzazione che può ridurre il time-to-market (tempo che intercorre fra l’inizio del processo di sviluppo di un nuovo prodotto e l’avvio della sua commercializzazione.) e facilitare la manutenzione futura. Inoltre, la stessa lingua sul lato client e sul lato server rende le applicazioni Node.js più veloci delle app che utilizzano lingue diverse.

 

Alta scalabilità

Non è una coincidenza che aziende come LinkedIn, Netflix o Twitter stiano passando a Node.js. Come è già stato descritto sopra, ci sono tre fattori principali che contribuiscono alla scalabilità di Node.js: può essere facilmente suddiviso in microservizi, ha un modello basato su eventi e ha un I / O non bloccante che aiuta a sfruttare al massimo la memoria della CPU e del computer. La scalabilità rende Node una buona scelta per le applicazioni che dovrebbero aumentare rapidamente il loro numero di utenti.

 

Alte prestazioni

Node.js si basa sul veloce e potente motore V8 di Chrome ed è una delle soluzioni lato server più veloci in circolazione. Inoltre, grazie alla sua architettura basata sugli eventi, i server Node.js sono in grado di elaborare più chiamate simultanee rispetto ad altri server.

Ciò rende Node.js una scelta perfetta per tutte le applicazioni in tempo reale, come chat o strumenti di collaborazione e tutti gli strumenti che richiedono prestazioni elevate.

 

Processo di sviluppo rapido

Le storie di aziende che passano a Node.js da Java e altre tecnologie sono ben note, sono già state descritte e sono in realtà la migliore prova del valore che Node.js apporta al processo di sviluppo. Quando PayPal ha deciso di passare a Node.js, ha creato la prima app Node in parallelo con un’applicazione Java equivalente. L’applicazione Node.js era:

  • costruito quasi due volte più velocemente con meno persone,
  • scritto con il 33% in meno di righe di codice,
  • costruito con il 40% di file in meno.

Un tempo di sviluppo più breve si traduce direttamente in un time-to-market più breve, che spesso determina il successo del tuo prodotto. Dopotutto, non importa quante buone le idee ti vengono in mente se i tuoi concorrenti offrono soluzioni simili prima di te.

 

Gestore di pacchetti eccezionale

Inizialmente, Node.js era inteso come un ambiente server per le applicazioni, ma gli sviluppatori hanno iniziato a usarlo per creare moduli per aiutarli nell’automazione delle attività locali. Da allora, un intero nuovo ecosistema di strumenti basati su nodi si è evoluto. Node Package Manager (NPM) installa i pacchetti che si desidera utilizzare e fornisce un’interfaccia utile per lavorare con essi.

 

Enorme comunità di utenti

La comunità dietro Node.js è grande e diventa più grande ogni giorno. Più grande è la comunità, più facile è ottenere supporto. Inoltre, la tecnologia stessa sta crescendo molto velocemente: una nuova versione viene rilasciata ogni 6 mesi, c’è una grande scelta di script, librerie e applicazioni open source che supportano Node.js.

 

Gestire richieste e operazioni simultanee

Grazie alle chiamate asincrone e all’I / O non bloccante di Node, più utenti possono modificare lo stesso file, spostare attività tra le schede, commentare, aggiungere file multimediali, tutto allo stesso tempo. La capacità di gestire le richieste contemporaneamente rende Node un ambiente perfetto per app Web in tempo reale come chat, giochi o strumenti di collaborazione.

Wooecommerce creazione responsive di e-commerce

Perché utilizzare Node.js

Tradizionalmente, JavaScript viene eseguito su un browser perché il kernel del browser è in realtà diviso in due parti: il motore di rendering e il motore JavaScript. Il primo è responsabile del rendering HTML e CSS, mentre il secondo è responsabile dell’esecuzione di JavaScript. Chrome utilizza il motore JavaScript, V8, che è molto veloce.

 

Node.js è un framework in esecuzione sul lato servizio e utilizza il motore V8 nella parte inferiore.

 

Sappiamo che Apache, PHP e Servlets di Java possono essere utilizzati per sviluppare pagine; Node.js funziona come loro, ma bisogna utilizzare JavaScript per svilupparli.

 

Node.js è un ottima opzione perchè è facile da usare, da sviluppare e anche da personalizzare, inoltre ci può lavorare anche un programmatore di front-end riducendo ulteriormente i costi.

 

Dal momento che PHP, Python e Java sono tutti disponibili per lo sviluppo back-end, perché imparare Node.js?

Dovremmo almeno sapere in quale scenario è meglio scegliere Node.js, nel complesso Node.js è adatto per i seguenti scenari:

  • Applicazioni in tempo reale, ad esempio strumenti di collaborazione multiplayer online, app di chat Web e altro ancora.
  • Si utilizza con le applicazioni high-concurrent basate su I/O, molto più veloce l’esecuzione di richieste rispetto a Java per cui si rivela la soluzione migliore per realizzare API che trasmettono i dati del database verso i client fornendo dati velocemente per i framework di front-end e mobile.

 

Il client fa ampio uso di connessioni lunghe, anche se il numero di richieste è alto, ma la maggior parte di loro sono connessioni inattive.

 

Node.js ha anche i suoi limiti; non è adatto per le attività che richiedono un uso intensivo della CPU come l’informatica dell’intelligenza artificiale, il video, l’elaborazione delle immagini e così via.

 

Concetti di base

A differenza dei client, uno dei dati che interessano gli sviluppatori sul lato server è il numero di richieste, ovvero il numero di client che il server può supportare.

 

Il problema all’epoca iniziale di C 10K è stato quello di discutere come supportare la richiesta di 10K con un singolo server. Naturalmente, con il miglioramento delle prestazioni hardware e software, c 10K non è più un problema, e stiamo cominciando a cercare di risolvere il problema C 10M, cioè come un singolo server gestisce la concorrenza di milioni di persone.

 

Quando C 10K è stato proposto, stavamo ancora usando il server Apache, che funziona lavorando su un sotto processo ed eseguendo script PHP in un sotto processo ogni volta che arriva una richiesta di rete.

 

Dopo l’esecuzione dello script, i risultati vengono inviati al client.

 

Ciò garantisce che il numero di processi che possono essere eseguiti sia limitato a circa poche migliaia, anche se un processo va storto e non influisce sull’intero server: il processo è un concetto pesante, ha un proprio heap e stack, occupa più memoria e ha un limite superiore al numero di processi che un server può eseguire, circa poche migliaia.

 

Anche se Apache in seguito ha utilizzato FastCGI, era essenzialmente un pool di processi che riduce il costo della creazione di processi, ma non aumenta in modo efficace il numero di richieste.

 

Servlet di Java utilizza un pool di thread, in cui ogni Servlet viene eseguito su un thread. Anche i thread, anche se più leggeri dei processi, sono relativi.

 

È stato testato che la dimensione dello stack che ogni thread possiede è 1M e non è ancora abbastanza efficiente. Inoltre, la programmazione multithreading può causare tutti i tipi di problemi, che i programmatori devono conoscere.

 

Se non si utilizzano thread, esistono altre due soluzioni: coroutine e I/O non bloccanti. Le richieste più leggere del thread e più coover possono essere eseguiti nello stesso thread e vengono inviati dal programmatore stesso, una tecnica ampiamente utilizzata nel linguaggio Go. Anziché bloccare l’I/O, node.js viene utilizzato per gestire scenari con un livello di record di informazioni simultanee.

 

L’I/O in questo caso può essere suddiviso in due categorie: I/O di rete e I/O di file, che in realtà sono molto simili. I/O può essere suddiviso in due passaggi, a partire dalla copia del contenuto di un file (rete) in un buffer che si trova in un’area di memoria esclusiva del sistema operativo. Il contenuto del buffer viene quindi copiato nell’area di memoria del programma utente.

 

Per bloccare l’I/O, entrambi i passaggi vengono bloccati, dall’attivazione di una richiesta di lettura, per il buffer pronto, al processo utente per il recupero dei dati.

 

L’I/O non bloccante esegue effettivamente il polling del kernel, se il buffer è pronto e, in caso contrario, continua con altre operazioni. Quando il buffer è pronto, il contenuto del buffer viene copiato nel processo utente e questo passaggio viene effettivamente bloccato.

 

Le tecniche di multiplexing di I/O si riferiscono all’uso di un singolo thread per elaborare più I/O di rete e spesso chiamiamo select, epoll, una funzione utilizzata per eseguire il polling di tutti i socket. Apache, ad esempio, utilizza il primo, mentre Nginx e Node.js utilizzano quest’ultimo, ad eccezione del fatto che quest’ultimo è più efficiente. Poiché il multiplexing I/O è in realtà un polling a thread singolo, è anche uno scenario di I/O non bloccante.

 

L’I/O asincrono è il modello di I/O ideale, ma purtroppo è vero che l’I/O asincrono non esiste. A I/O su Linux passa i dati attraverso segnali e callback, ma è difettoso. I libeios e i CIO esistenti in Windows utilizzano essenzialmente pool di thread e I/O di blocco per simulare l’I/O asincrono.

 

Modello di thread Node.js thread model

Molti articoli menzionano che Node.js è a thread singolo, ma questo non è rigoroso e persino irresponsabile:

  • In che modo Node.js gestisce le richieste simultanee in un thread?
  • In che modo Node.js esegue l’I/O asincrono dei file in un thread?
  • In che modo Node.js utilizza la potenza di elaborazione di più CPU sul server?

 

I/O di rete Node.js gestisce un numero elevato di richieste simultanee in un singolo thread, ma ciò richiede alcune competenze di programmazione.

 

Questo perché Node.js è basato su eventi, il che significa che la funzione di callback viene eseguita solo quando si verifica la richiesta di rete. Quando arrivano più richieste, si mettono in coda e attendono l’esecuzione.

 

Questo può sembrare naturale, ma la mancata comprensione che Node.js è in esecuzione su un singolo thread e che le funzioni di callback vengono eseguite in modo sincrono, durante lo sviluppo di programmi nel modello tradizionale, può causare gravi problemi. Come semplice esempio, la stringa “Hello World” qui potrebbe essere il risultato dell’esecuzione di un altro modulo. Supponendo che la generazione di “Hello World” richieda molto tempo, blocca il callback della richiesta di rete corrente, causando la mancata risposta alla richiesta di rete successiva.

 

La soluzione è semplice, con il meccanismo di callback asincrono. È possibile passare il parametro di risposta utilizzato per produrre l’output agli altri moduli, generare l’output in modo asincrono ed infine eseguire l’output reale nella funzione di callback. Il vantaggio è che la funzione di callback di http.createServer non si blocca, pertanto non vi è alcuna richiesta senza risposta.

 

Poiché si esegue la manutenzione del client, tutto il codice è sempre a thread singolo, sequenziale.

 

Infatti, Node.js gestisce un pool di thread nella parte inferiore. Come accennato in precedenza nella sezione Concetti di base, non esiste un I/O di file asincrona reale, in genere simulata da un pool di thread. Per impostazione predefinita, nel pool di thread sono presenti quattro thread per l’I/O di file.

 

È importante notare che non è possibile modificare direttamente i pool di thread sottostanti e non è necessario preoccuparsi della loro esistenza. I pool di thread vengono utilizzati solo per eseguire operazioni di I/O, non operazioni che richiedono un uso intensivo della CPU, ad esempio immagini, elaborazione video, calcolo di massa e così via.

 

Se ci sono un piccolo numero di attività che richiedono un uso intensivo della CPU da gestire, possiamo avviare più processi Node.js e utilizzare il meccanismo IPC per la comunicazione interprocesso o chiamare un programma C/Java esterno. Se si dispone di un numero elevato di attività che richiedono un utilizzo intensivo della CPU, è solo una decisione negativa scegliere Node.js.

 

Svuotare la CPU

Finora, abbiamo appreso che Node.js utilizza la tecnologia di multiplexing di I/O per simulare l’I/O di file asincrono usando un I/O di rete a thread singolo, usando un pool di thread e un numero ridotto di thread. Il thread singolo di node.js sembra lento su una CPU a 32 core?

 

La risposta è no, possiamo avviare più processi Node.js. A differenza della sezione precedente, i processi non necessitano di comunicazioni tra questi.

 

La regola di bilanciamento del carico predefinita consiste nell’assegnare le richieste di rete a porte diverse a turno. Inoltre possiamo inoltrare le richieste di rete al processo Node.js con il minor numero di connessioni con il flag least_conn oppure possiamo usare ip_hash per garantire che le richieste per lo stesso indirizzo IP debbano essere gestite dallo stesso processo Node.js.

 

Più processi Node.js sfruttano appieno la potenza di elaborazione delle CPU multicore e dispongono di una potente capacità di espansione.

 

Ciclo di eventi

C’è un ciclo di eventi in Node.js e gli studenti con esperienza nello sviluppo di iOS possono sentirsi familiari. Sì, è un po’ simile a Runloop, cioè un ciclo di eventi completo può anche essere suddiviso in fasi, seguite da poll, check, callback di chiusura, timer, callback I/O e Idle.

 

Poiché Node.js è basato su eventi, la funzione di callback per ogni evento viene registrata in fasi diverse del ciclo di eventi. Ad esempio, la funzione di callback di fs.readFile viene aggiunta ai callback di I/O, i callback setImmediate vengono aggiunti alla fase di polling loop successiva dopo la fine e il callback syrfor.nextTick() viene aggiunto alla fine della fase corrente prima dell’inizio della fase successiva.

 

È importante sapere che i callback per diversi metodi asincroni vengono eseguiti in fasi diverse, altrimenti si avranno errori logici a causa del problema relativo all’ordine delle chiamate.

 

Event Loop continua a ciclo, con tutte le funzioni di callback registrate in quella fase che vengono eseguite in modo sincrono in ogni fase. Ecco perché ho menzionato nella sezione I/O di rete che non chiamano metodi di blocco nelle funzioni di callback, sempre utilizzando idee asincrone per operazioni che richiedono molto tempo. Una funzione di callback che richiede troppo tempo può lasciare la scheda Event Loop in una fase lunga e la nuova richiesta di rete non sarà in grado di rispondere in modo tempestivo.

 

Molti moduli in Node.js vengono ereditati da EventEmitter, ad esempio fs.readStream menzionato nella sezione successiva, che crea un flusso di file leggibile che apre i file, legge i dati e genera eventi al termine delle letture.

 

Flusso di dati

I vantaggi dell’utilizzo del flusso di dati sono evidenti e nella vita sono presenti immagini reali. Ad esempio, l’insegnante ha assegnato i compiti estivi, se gli studenti ne faranno un po ‘(flusso di compiti a casa) ogni giorno, è più facile completare l’attività. Se aspettano l’ultimo giorno, di fronte si troveranno una montagna da superare di compiti, si sentiranno incapaci di fare.

 

Lo stesso vale per lo sviluppo del server, supponendo che l’utente carica un file 1G o legge un file 1G locale. Se non esiste un concetto di flusso di dati, è necessario aprire un buffer di dimensioni 1G e quindi lavorare centralmente una volta dopo che il buffer è pieno.

 

Sotto forma di flusso di dati, è possibile definire un buffer molto piccolo, ad esempio 1MB di dimensioni. Quando il buffer è pieno, viene eseguita una funzione di callback per elaborare questo piccolo dato per evitare un backlog.
Con la tecnologia della pipeline, è possibile scrivere contenuto da un flusso a un altro: “With pipeline technology, you can write content from one stream to another”.

 

Diversi flussi possono anche essere collegati in serie, come la lettura di un file compresso, la decompressione durante la lettura e la scrittura del contenuto.

 

Riassunto

Per connessioni simultanee lunghe, il modello basato su eventi è molto più leggero dei thread e più processi Node.js possono essere facilmente espansi con il bilanciamento del carico. Questo rende Node.js ideale per le applicazioni che richiedono un uso intensivo di I/O come le richieste API dagli endpoint..
“This makes Node.js ideal for I/O-intensive applications”.

 

Lo svantaggio di questo approccio, tuttavia, è che non si è bravi nelle attività che richiedono un uso intensivo della CPU.

I dati sono spesso descritti in modo scorrevole in Node.js, che fornisce anche un buon incapsulamento.

 

Node.js viene sviluppato utilizzando il linguaggio front-end (JavaScript) ed è anche un server back-end, fornendo così una buona idea per la separazione front-end.