Как изящно перезапустить сервер NodeJS? - PullRequest
22 голосов
/ 20 января 2012

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

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

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

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

Ответы [ 3 ]

16 голосов
/ 12 июня 2012

Вы можете обрабатывать сигналы 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);
            }
        });
    }
}
2 голосов
/ 20 января 2012

Есть модуль с именем Навсегда .

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

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

1 голос
/ 21 января 2015

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

...