Come posso evitare che node.js si arresti in modo anomalo? try-catch non funziona

Dalla mia esperienza, un server php lanciava un’eccezione al log o al server, ma node.js semplicemente si blocca. Circondare il mio codice con un try-catch non funziona, dal momento che tutto viene eseguito in modo asincrono. Mi piacerebbe sapere cosa fanno gli altri nei loro server di produzione.

Altre risposte sono davvero folle, come puoi leggere dai documenti di Node su http://nodejs.org/docs/latest/api/process.html#process_event_uncaughtexception

Se qualcuno sta usando altre risposte dichiarate, leggi Node Docs:

Si noti che uncaughtException è un meccanismo molto grezzo per la gestione delle eccezioni e potrebbe essere rimosso in futuro

Quindi, dopo aver attraversato, ho finalmente trovato quello che suggerisce il documento Node:

Non usarlo, usa invece domains con cluster . Se usi uncaughtException , riavvia l’applicazione dopo ogni eccezione non gestita!

La soluzione è DOMAIN con Cluster

Quello che effettivamente facciamo è inviare una risposta di errore alla richiesta che ha triggersto l’errore, lasciando che gli altri finiscano nel loro tempo normale e interrompere l’ascolto di nuove richieste in quel lavoratore.

In questo modo, l’utilizzo del dominio va di pari passo con il modulo cluster, poiché il processo master può eseguire il fork di un nuovo worker quando un lavoratore incontra un errore. Vedere il codice qui sotto per capire cosa intendo

Utilizzando Domain e la capacità di separare il nostro programma in più processi di lavoro utilizzando Cluster , possiamo reactjs in modo più appropriato e gestire gli errori con maggiore sicurezza.

 var cluster = require('cluster'); var PORT = +process.env.PORT || 1337; if(cluster.isMaster) { cluster.fork(); cluster.fork(); cluster.on('disconnect', function(worker) { console.error('disconnect!'); cluster.fork(); }); } else { var domain = require('domain'); var server = require('http').createServer(function(req, res) { var d = domain.create(); d.on('error', function(er) { //something unexpected occurred console.error('error', er.stack); try { //make sure we close down within 30 seconds var killtimer = setTimeout(function() { process.exit(1); }, 30000); // But don't keep the process open just for that! killtimer.unref(); //stop taking new requests. server.close(); //Let the master know we're dead. This will trigger a //'disconnect' in the cluster master, and then it will fork //a new worker. cluster.worker.disconnect(); //send an error to the request that triggered the problem res.statusCode = 500; res.setHeader('content-type', 'text/plain'); res.end('Oops, there was a problem!\n'); } catch (er2) { //oh well, not much we can do at this point. console.error('Error sending 500!', er2.stack); } }); //Because req and res were created before this domain existed, //we need to explicitly add them. d.add(req); d.add(res); //Now run the handler function in the domain. d.run(function() { //You'd put your fancy application logic here. handleRequest(req, res); }); }); server.listen(PORT); } 

Sebbene Domain sia in attesa di deprecazione, verrà rimosso non appena la nuova sostituzione avrà luogo come indicato nella Documentazione del nodo

Questo modulo è in attesa di deprecazione. Una volta completata l’API di sostituzione, questo modulo sarà completamente deprecato. Gli utenti che devono assolutamente disporre delle funzionalità fornite dai domini possono affidarsi al momento, ma in futuro dovrebbero aspettarsi di dover eseguire la migrazione a una soluzione diversa.

Ma fino a quando non viene introdotta la nuova sostituzione, Domain with Cluster è l’unica soluzione valida suggerita da Documentazione nodo.

Per una comprensione approfondita del Domain e del Cluster leggere

https://nodejs.org/api/domain.html#domain_domain ( Stability: 0 - Deprecated )

https://nodejs.org/api/cluster.html

Grazie a @Stanley Luo per averci condiviso questa meravigliosa e approfondita spiegazione su Cluster e Domini

Cluster e domini

Ho messo questo codice proprio sotto le mie dichiarazioni obbligatorie e le dichiarazioni globali:

 process.on('uncaughtException', function (err) { console.error(err); console.log("Node NOT Exiting..."); }); 

per me va bene. l’unica cosa che non mi piace è che non ottengo tante informazioni come vorrei se lasciassi andare in crash.

Come accennato qui troverete error.stack fornisce un messaggio di errore più completo come il numero di riga che ha causato l’errore:

 process.on('uncaughtException', function (error) { console.log(error.stack); }); 

Prova il supervisor

 npm install supervisor supervisor app.js 

Oppure puoi installare forever invece.

Tutto ciò che farà è recuperare il tuo server quando si blocca riavviandolo.

forever può essere utilizzato all’interno del codice per ripristinare con garbo qualsiasi processo che si blocca.

I documenti forever hanno informazioni solide sulla gestione dell’uscita / errore a livello di codice.

L’uso di try-catch può risolvere gli errori non rilevati, ma in alcune situazioni complesse, non svolgerà il lavoro giusto come la funzione asincrona. Ricorda che in Node, qualsiasi chiamata di funzione asincrona può contenere una potenziale operazione di arresto anomalo dell’app.

L’utilizzo di uncaughtException è una soluzione alternativa, ma è riconosciuta come inefficiente ed è probabile che venga rimossa nelle future versioni di Node, quindi non contare su di essa.

La soluzione ideale è utilizzare il dominio: http://nodejs.org/api/domain.html

Per assicurarti che la tua app sia funzionante, anche il tuo server si è arrestato in modo anomalo, procedi nel seguente modo:

  1. utilizzare il nodo cluster per eseguire il fork di più processi per core. Quindi, se un processo è morto, un altro processo sarà avviato automaticamente. Controlla: http://nodejs.org/api/cluster.html

  2. usa il dominio per catturare l’operazione asincrona invece di usare try-catch o uncaught. Non sto dicendo che cercare di catturare o di prendere in contropiede sia un cattivo pensiero!

  3. usa per sempre / supervisore per monitorare i tuoi servizi

  4. aggiungi daemon per eseguire l’app per i nodes: http://upstart.ubuntu.com

spero che questo ti aiuti!

Provate il modulo del nodo pm2 è molto coerente e ha una grande documentazione. Gestore dei processi di produzione per le app Node.js con un sistema di bilanciamento del carico integrato. si prega di evitare uncaughtException per questo problema. https://github.com/Unitech/pm2

UncaughtException è “un meccanismo molto rozzo” (così vero) e ora i domini sono deprecati. Tuttavia, abbiamo ancora bisogno di un meccanismo per catturare gli errori nei domini (logici). La Biblioteca:

https://github.com/vacuumlabs/yacol

può aiutarti a fare questo Con un po ‘di scrittura in più puoi avere una bella semantica di domini tutto intorno al tuo codice!

Funziona alla grande su restify:

 server.on('uncaughtException', function (req, res, route, err) { log.info('******* Begin Error *******\n%s\n*******\n%s\n******* End Error *******', route, err.stack); if (!res.headersSent) { return res.send(500, {ok: false}); } res.write('\n'); res.end(); });