¿Cómo evito que node.js se cuelgue? try-catch no funciona

Desde mi experiencia, un servidor php lanzaría una excepción al registro o al servidor, pero node.js simplemente se bloquea. Rodear mi código con un try-catch tampoco funciona, ya que todo se hace de forma asíncrona. Me gustaría saber qué hacen los demás en sus servidores de producción.

Otras respuestas son realmente insanas, como puede leer en los propios documentos de Node en http://nodejs.org/docs/latest/api/process.html#process_event_uncaughtexception

Si alguien está usando otras respuestas indicadas, lea Node Docs:

Tenga en cuenta que uncaughtException es un mecanismo muy tosco para el manejo de excepciones y puede eliminarse en el futuro.

Entonces, después de pasar, finalmente descubrí lo que sugiere el propio documento Node:

No lo use, use domains con cluster lugar. Si usa uncaughtException , reinicie su aplicación después de cada excepción no controlada.

La solución es DOMINIO con clúster

Lo que realmente hacemos es enviar una respuesta de error a la solicitud que desencadenó el error, dejando que los demás terminen en su tiempo normal, y dejar de escuchar nuevas solicitudes en ese trabajador.

De esta manera, el uso del dominio va de la mano con el módulo de clúster, ya que el proceso maestro puede bifurcar a un nuevo trabajador cuando un trabajador encuentra un error. Vea el código a continuación para entender a qué me refiero

Al usar Domain , y la flexibilidad de separar nuestro progtwig en múltiples procesos de trabajo utilizando Cluster , podemos reactjsr de forma más adecuada y manejar errores con mucha mayor seguridad.

 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); } 

Aunque Domain está pendiente de obsolescencia y será eliminado ya que el nuevo reemplazo viene como se indica en la Documentación de Node

Este módulo está pendiente de desaprobación. Una vez que se haya finalizado una API de reemplazo, este módulo quedará completamente obsoleto. Los usuarios que absolutamente deben tener la funcionalidad que proporcionan los dominios pueden confiar en ello por el momento, pero deberían tener que migrar a una solución diferente en el futuro.

Pero hasta que no se presente el nuevo reemplazo, Dominio con clúster es la única buena solución que sugiere la Documentación de nodos.

Para una comprensión más profunda Domain y Cluster leídos

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

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

Gracias a @Stanley Luo por compartir esta maravillosa explicación en profundidad sobre clúster y dominios

Grupo y dominios

Puse este código justo debajo de mis declaraciones requeridas y declaraciones globales:

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

funciona para mi. lo único que no me gusta es que no obtengo tanta información como lo haría si dejo que la cosa se cuelgue.

Como se mencionó aquí , encontrará error.stack proporciona un mensaje de error más completo, como el número de línea que causó el error:

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

Prueba con el supervisor

 npm install supervisor supervisor app.js 

O puede instalarlo forever .

Todo lo que hará es recuperar su servidor cuando se bloquea al reiniciarlo.

forever se puede usar dentro del código para recuperar con gracia cualquier proceso que se cuelgue.

Los documentos forever tienen información sólida sobre el manejo de salida / error programáticamente.

El uso de try-catch puede resolver los errores no detectados, pero en algunas situaciones complejas, no hará bien el trabajo, como capturar la función asincrónica. Recuerde que en Node, cualquier llamada a función asíncrona puede contener una operación potencial de locking de aplicaciones.

El uso de uncaughtException es una solución, pero se reconoce como ineficiente y es probable que se elimine en las versiones futuras de Node, por lo tanto, no cuente con ello.

La solución ideal es usar dominio: http://nodejs.org/api/domain.html

Para asegurarte de que tu aplicación esté funcionando correctamente incluso si el servidor se bloqueó, sigue estos pasos:

  1. utilice el clúster de nodos para unir múltiples procesos por núcleo. Entonces, si un proceso murió, otro proceso se iniciará automáticamente. Consulte: http://nodejs.org/api/cluster.html

  2. use domain para capturar la operación asincrónica en lugar de usar try-catch o uncaught. ¡No estoy diciendo que try-catch o uncaught es una mala idea!

  3. use forever / supervisor para controlar sus servicios

  4. agrega daemon para ejecutar tu aplicación de nodo: http://upstart.ubuntu.com

¡espero que esto ayude!

Pruebe con el módulo de nodo PM2, es muy consistente y tiene una gran documentación. Administrador de procesos de producción para aplicaciones Node.js con un equilibrador de carga incorporado. por favor, evita la excepción no detectada para este problema. https://github.com/Unitech/pm2

UncaughtException es “un mecanismo muy tosco” (tan cierto) y los dominios están en desuso ahora. Sin embargo, todavía necesitamos algún mecanismo para detectar errores en los dominios (lógicos). La biblioteca:

https://github.com/vacuumlabs/yacol

puede ayudarte a hacer esto ¡Con un poco de escritura adicional puede tener una buena semántica de dominio alrededor de su código!

Funciona muy bien en 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(); });