start run node making always alive node.js unix-socket forever

node.js - run - Cierre bien el servidor de zócalos UNIX en NodeJS que se ejecuta en Forever



pm2 node service (5)

Tengo una aplicación NodeJS que configura un socket UNIX para exponer algún canal de comunicación entre procesos (algún tipo de control). El archivo de socket UNIX se coloca en la carpeta os.tmpdir() (es decir, /tmp/app-monitor.sock ).

var net = require(''net''); var server = net.createServer(...); server.listen(''/tmp/app-monitor.sock'', ...);

Uso un control de señal (SIGINT, SITERM, etc.) para apagar mi servidor y eliminar un archivo de socket.

function shutdown() { server.close(); // socket file is automatically removed here process.exit(); } process.on(''SIGINT'', shutdown); // and so on

Mi aplicación se está ejecutando forever start ... para monitorear su ciclo de vida.

Tengo un problema con el comando forever restartall . Cuando hace siempre restartall , está utilizando un SIGKILL para terminar todos los procesos secundarios. SIGKILL no puede ser manejado por un proceso, por lo que mi aplicación muere sin ningún procedimiento de cierre.

El problema es un archivo de socket que no se elimina cuando se utiliza SIGKILL . Después de reiniciar el proceso hijo, no se puede iniciar el nuevo servidor porque una llamada de listen causará un error EADDRINUSE .

No puedo eliminar un archivo de socket existente durante el inicio de una aplicación porque no sé si es un socket que funciona realmente o algunos rastros de un cierre impuro anterior.

Entonces, la pregunta es ... ¿Cuál es la mejor manera de manejar tal situación (SIGKILL y servidor de socket UNIX)?


Como han mencionado otras personas, no puede hacer nada en respuesta a SIGKILL, que es en general el motivo por el cual, forever todos (y todos los demás) no utilicen SIGKILL, excepto en circunstancias extremas. Así que lo mejor que puedes hacer es limpiar en otro proceso.

Te sugiero que limpies al comienzo. Cuando obtenga EADDRINUSE , intente conectarse al zócalo. Si la conexión de socket se realiza correctamente, se está ejecutando otro servidor y, por lo tanto, esta instancia debería salir. Si la conexión falla, es seguro desvincular el archivo de socket y crear uno nuevo.

var fs = require(''fs''); var net = require(''net''); var server = net.createServer(function(c) { //''connection'' listener console.log(''server connected''); c.on(''end'', function() { console.log(''server disconnected''); }); c.write(''hello/r/n''); c.pipe(c); }); server.on(''error'', function (e) { if (e.code == ''EADDRINUSE'') { var clientSocket = new net.Socket(); clientSocket.on(''error'', function(e) { // handle error trying to talk to server if (e.code == ''ECONNREFUSED'') { // No other server listening fs.unlinkSync(''/tmp/app-monitor.sock''); server.listen(''/tmp/app-monitor.sock'', function() { //''listening'' listener console.log(''server recovered''); }); } }); clientSocket.connect({path: ''/tmp/app-monitor.sock''}, function() { console.log(''Server running, giving up...''); process.exit(); }); } }); server.listen(''/tmp/app-monitor.sock'', function() { //''listening'' listener console.log(''server bound''); });


Debería poder utilizar SIGTERM para hacer lo que quiera: process.on(''SIGTERM'', shutdown)


Ya que no puede manejar SIGKILL y quiere usar para siempre (que usa SIGKILL ) tendrá que usar una solución alternativa.

Por ejemplo, primero envíe una señal para apagar su servidor y luego reinicie para siempre:

kill -s SIGUSR1 $pid # $pid contains the pid of your node process, or use # killall -SIGUSR1 node sleep 2 forever restart test.js

En su js manejar SIGUSR1:

process.on(''SIGUSR1'', gracefullyShutdownMyServer);


debe elegir

  1. cambie SIGKILL a otra señal en forever-monitor para manejar en la aplicación
  2. Cuida tu aplicación en este caso, utilizando fs.unlink.
  3. deja de usar para siempre

server.on(''error'', function (e) { if (e.code == ''EADDRINUSE'') { console.log(''Address in use, retrying...''); setTimeout(function () { server.close(); server.listen(PORT, HOST); }, 1000); } });

http://nodejs.org/api/net.html#net_server_listen_port_host_backlog_callback

UPD

no puedes manejar SIGKILL, entonces debes limpiar el manual del zócalo

este ejemplo funciona bien para siempre

var fs = require(''fs''); var net = require(''net''); var server = net.createServer(function(c) {}); server.listen(''./app-monitor.sock'', function() { console.log(''server bound''); }); server.on(''error'', function (e) { if (e.code == ''EADDRINUSE'') { console.log(''Address in use, retrying...''); setTimeout(function () { fs.unlink(''./app-monitor.sock''); }, 1000); } });