2012-01-19 21 views
18

Actualmente, mi entorno de prueba para un proyecto paralelo es un repositorio git, donde inserto un código, elimino el servidor manualmente con Ctrl-C y lo reinicio manualmente.Cómo reiniciar correctamente un servidor NodeJS?

Me doy cuenta de que hay muchas cosas malas con esto. Por ejemplo, ¿qué pasa si un usuario todavía está en el medio de hacer algo importante y el proceso está procesando datos confidenciales, y simplemente lo maté?

Cuando utilicé el nodo v0.4.x había un buen módulo de Clúster que podía reiniciar el servidor con elegancia, cuando la aplicación está en un estado silencioso. En v0.6.x, el módulo de clúster está integrado en el nodo, pero es realmente, muy simple, y no tiene la capacidad de reinicio elegante.

¿Alguien sabe cómo puedo reiniciar con gracia un servidor nodejs en v0.6.x?

Respuesta

2

Hay un módulo llamado Forever.

Esto puede reiniciar el proceso con gracia. Supongo que entonces puedes ejecutar varias instancias con clúster (una en cada núcleo) y usar Forever para monitorear/reiniciar.

Esto es solo una opción que encontré; ¡Estoy abierto a sugerencias!

16

Puede manejar las señales POSIX en el código de nodo.

Ver en el ejemplo de código, que se encargará de SIGINT (Ctrl-C por ejemplo) como una señal de parada para todos los trabajadores en racimo, y SIGUSR2 simplemente se reiniciará todos los trabajadores

Así, la emisión de kill -SIGUSR2 PID, donde PID es maestro nodo PID se reiniciará toda agrupación

module.exports = function(app) { 
    var cluster = require('cluster'); 
    var numCPUs = require('os').cpus().length; 
    var workerList = new Array(); 
    var sigkill = false; 

    if (cluster.isMaster) { 
     for (var i = 0; i < numCPUs; i++) { 
      var env = process.env; 
      var worker = cluster.fork(env); 
      workerList.push(worker); 
     } 

     process.on('SIGUSR2',function(){ 
      console.log("Received SIGUSR2 from system"); 
      console.log("There are " + workerList.length + " workers running"); 
      workerList.forEach(function(worker){ 
       console.log("Sending STOP message to worker PID=" + worker.pid); 
       worker.send({cmd: "stop"}); 
      }); 
     }); 

     process.on('SIGINT',function(){ 
      sigint = true; 
      process.exit(); 
     }); 

     cluster.on('death', function(worker) { 
      if (sigkill) { 
       logger.warn("SIGKINT received - not respawning workers"); 
       return; 
      } 
      var newWorker = cluster.fork(); 
      console.log('Worker ' + worker.pid + ' died and it will be re-spawned'); 

      removeWorkerFromListByPID(worker.pid); 
      workerList.push(newWorker); 
     }); 
    } else { 
     process.on('message', function(msg) { 
      if (msg.cmd && msg.cmd == 'stop') { 
       console.log("Received STOP signal from master"); 
       app.close(); 
       process.exit(); 
      } 
     }); 
     app.listen(3000); 
    } 

    function removeWorkerFromListByPID(pid) { 
     var counter = -1; 
     workerList.forEach(function(worker){ 
      ++counter; 
      if (worker.pid === pid) { 
       workerList.splice(counter, 1); 
      } 
     }); 
    } 
} 
+0

¿No necesita el controlador 'SIGUSR2' hacer algo para reiniciar el proceso que acaba de detener? –

+0

Oh, ya veo ... ¿Creo que el evento de 'muerte' ahora es 'salir' en el nodo v0.10? –

+0

Una pregunta más ... esto reinicia el servidor correctamente, pero no vuelve a cargar el código del servidor, ¿correcto? Eso tomaría algún tipo de proceso de monitoreo externo? –

1

también hay un módulo llamado PM2. Tiene la capacidad de detener todos los procesos en un clúster.

+0

-1; Probé la capacidad de recarga "elegante" de PM2 y hasta donde puedo decir [simplemente no funciona] (https://github.com/Unitech/pm2/issues/3078) en este momento. No puedo prometer que ninguna de las otras respuestas aquí funcione mejor, pero estoy * seguro de que este es un callejón sin salida frustrante y que hace perder el tiempo. –

Cuestiones relacionadas