2012-01-19 50 views
18

目前,我的一個側面項目的prod環境是一個git倉庫,我在這裏拖入一些代碼,用Ctrl-C手動終止服務器,然後手動重啓它。如何正常重啓NodeJS服務器?

我意識到這有很多錯誤的東西。例如,如果用戶仍在做重要的事情,並且這個過程正在處理敏感數據,那麼我會殺了它?

當我使用節點v0.4.x時,有一個很好的集羣模塊可以在應用程序處於安靜狀態時正常重啓服務器。在v0.6.x中,Cluster模塊內置在節點中,但它確實是非常裸露的,並且沒有優雅的重啓能力。

任何人都知道我可以在v0.6.x中正常重新啓動nodejs服務器嗎?

回答

2

有一個名爲Forever的模塊。

可以優雅地重新啓動進程。我想你可以以某種方式運行多個集羣實例(每個核心都有一個實例)並使用Forever來監視/重新啓動它們。

這只是我找到的一個選項;我接受建議!

16

您可以在節點代碼中處理POSIX信號。

參見例如代碼,將處理SIGINT(Ctrl-C鍵,例如),作爲所有羣集工人STOP信號,和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

哦,我明白了......我認爲'死亡'事件現在在節點v0.10中'退出'了? –

+0

還有一個問題......它會優雅地重新啓動服務器,但它根本沒有重新加載服務器代碼,對嗎?那需要進行某種外部監控? –

1

還有一個名爲PM2的模塊。它有能力阻止集羣中的所有進程。

+0

-1;我嘗試了PM2的「優雅」重新加載功能,並且據我所知[現在只是簡單的不工作](https://github.com/Unitech/pm2/issues/3078)。我不能保證任何其他答案在這裏工作得更好,但我*確信這是一個令人沮喪和浪費時間的死衚衕。 –

相關問題