2012-01-19 2 views
18

В настоящее время моя среда prod для стороннего проекта - это git repo, где я вытягиваю код, вручную убиваю сервер с помощью Ctrl-C и перезапускаю его вручную.Как изящно перезапустить сервер NodeJS?

Я понимаю, что с этим что-то не так. Например, что, если пользователь все еще находится в середине делающего что-то важное, и процесс хрустет конфиденциальные данные, и я просто убил его ?!

Когда я использовал узел v0.4.x, был хороший модуль Cluster, который мог бы перезагрузить сервер изящно, когда приложение находится в тихом состоянии. В v0.6.x модуль Cluster встроен в узел, но он действительно, действительно голый, и не имеет изящной возможности перезапуска.

Кто-нибудь знает, как я могу изящно перезапустить сервер nodejs в v0.6.x?

ответ

2

Существует модуль с именем Forever.

Это может изящно перезапустить процесс. Полагаю, что вы можете каким-то образом запустить несколько экземпляров с кластером (по одному на каждое ядро) и использовать Forever для мониторинга/перезапуска их.

Это только вариант, который я нашел; Я открыт для предложений!

16

Вы можете обрабатывать сигналы POSIX в коде узла.

См пример кода, который будет обрабатывать SIGINT (Ctrl-C, например) в качестве сигнала останова для всех кластерных рабочих и SIGUSR2 просто перезапустить все рабочие

Так, выпуск kill -SIGUSR2 PID, где PID является мастер узла PID будет перезагружен все кассетные

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

Не нужно ли обработчику 'SIGUSR2' что-то делать, чтобы перезапустить процесс, который он просто остановил? –

+0

О, я вижу ... Я думаю, что событие «смерти» теперь «выходит» в Node v0.10? –

+0

Еще один вопрос ... это изящно перезапускает сервер, но он не перезагружает серверный код вообще, правильно? Это потребует какого-то внешнего мониторинга? –

1

Там также модуль с именем PM2. Он имеет возможность остановить все процессы в кластере.

+0

-1; Я опробовал «изящную» возможность перезагрузки PM2 и, насколько я могу судить, [просто не работает] (https://github.com/Unitech/pm2/issues/3078) прямо сейчас. Я не могу пообещать, что любой из других ответов здесь работает лучше, но я уверен, что это разочаровывает и тратит время на тупик. –

Смежные вопросы