【问题标题】:How to gracefully restart a NodeJS server?如何优雅地重启 NodeJS 服务器?
【发布时间】:2012-02-14 13:55:16
【问题描述】:

目前,我的辅助项目的 prod 环境是一个 git repo,我在其中提取一些代码,使用 Ctrl-C 手动终止服务器,然后手动重新启动它。

我意识到这有很多问题。例如,如果用户仍在做一些重要的事情,而该过程正在处理敏感数据,而我刚刚杀死了它怎么办?!

当我使用 node v0.4.x 时,有一个不错的集群模块可以在应用程序处于安静状态时优雅地重新启动服务器。在 v0.6.x 中,Cluster 模块内置在 node 中,但它非常非常裸露,并且没有优雅重启的能力。

有人知道我如何在 v0.6.x 中优雅地重启 nodejs 服务器吗?

【问题讨论】:

    标签: node.js cluster-computing restart


    【解决方案1】:

    您可以在节点代码中处理 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(){
                sigkill = 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);
                }
            });
        }
    }
    

    【讨论】:

    • SIGUSR2 处理程序是否需要重新启动它刚刚停止的进程?
    • 哦,我明白了……我认为 Node v0.10 中的“死亡”事件现在是“退出”?
    • 还有一个问题……这会优雅地重新启动服务器,但它根本不会重新加载服务器代码,对吗?这需要某种外部监控过程吗?
    【解决方案2】:

    还有一个名为PM2 的模块。它能够停止集群中的所有进程。

    【讨论】:

    • -1;我尝试了 PM2 的“优雅”重新加载功能,据我所知just plain doesn't work 现在。我不能保证这里的任何其他答案都会更好,但我确定这是一个令人沮丧且浪费时间的死胡同。
    【解决方案3】:

    有一个名为Forever的模块。

    这可以优雅地重新启动该过程。我想你可以以某种方式使用集群运行多个实例(每个核心上一个)并使用 Forever 来监控/重新启动它们。

    这只是我找到的一个选项;我愿意接受建议!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-14
      • 1970-01-01
      • 2017-01-20
      • 1970-01-01
      • 2010-09-06
      • 1970-01-01
      • 1970-01-01
      • 2013-01-24
      相关资源
      最近更新 更多