NodeJS на нескольких процессорах (PM2, Cluster, Recluster, nought)

Я изучаю варианты запуска узла в многоядерной среде.

Я пытаюсь определить наилучший подход и до сих пор я видел эти варианты

  • используйте встроенную библиотеку кластеров для запуска работ и ответа на сигналы
  • используйте PM, но PM2-i указан как бета-версия.
  • нет
  • Recluster

есть ли другие альтернативы? Что люди используют в производстве?

3 ответов


Я использую библиотеку кластеров по умолчанию, и она работает очень хорошо. У меня было более 10 000 совпадений (несколько кластеров на нескольких серверах), и он работает очень хорошо.

для обработки ошибок предлагается использовать кластеры с доменом.

это снято прямо из http://nodejs.org/api/domain.html я внес некоторые изменения в то, как он порождает новые кластеры для каждого ядра вашей машины. и избавился от if / else и добавил express.

var cluster = require('cluster'),
    http = require('http'),
    PORT = process.env.PORT || 1337,
    os = require('os'),
    server;

function forkClusters () {
    var cpuCount = os.cpus().length;
    // Create a worker for each CPU
    for (var i = 0; i < cpuCount ; i += 1) {
        cluster.fork();
    }
}

// Master Process
if (cluster.isMaster) {

    // You can also of course get a bit fancier about logging, and
    // implement whatever custom logic you need to prevent DoS
    // attacks and other bad behavior.
    //
    // See the options in the cluster documentation.
    //
    // The important thing is that the master does very little,
    // increasing our resilience to unexpected errors.

    forkClusters ()

    cluster.on('disconnect', function(worker) {
        console.error('disconnect!');
        cluster.fork();
    });

}
function handleError (d) {
    d.on('error', function(er) {
        console.error('error', er.stack);

        // Note: we're in dangerous territory!
        // By definition, something unexpected occurred,
        // which we probably didn't want.
        // Anything can happen now!Be very careful!

        try {
            // make sure we close down within 30 seconds
            var killtimer = setTimeout(function() {
                process.exit(1);
            }, 30000);
            // But don't keep the process open just for that!
            killtimer.unref();

            // stop taking new requests.
            server.close();

            // Let the master know we're dead.This will trigger a
            // 'disconnect' in the cluster master, and then it will fork
            // a new worker.
            cluster.worker.disconnect();
        } catch (er2) {
            // oh well, not much we can do at this point.
            console.error('Error sending 500!', er2.stack);
        }
    });
}
// child Process
if (cluster.isWorker) {
    // the worker
    //
    // This is where we put our bugs!

    var domain = require('domain');
    var express = require('express');
    var app = express();
    app.set('port', PORT);

    // See the cluster documentation for more details about using
    // worker processes to serve requests.How it works, caveats, etc.

    var d = domain.create();
    handleError(d);

    // Now run the handler function in the domain.
    //
    // put all code here. any code included outside of domain.run will not handle errors on the domain level, but will crash the app.
    //

    d.run(function() {
        // this is where we start our server
        server = http.createServer(app).listen(app.get('port'), function () {
            console.log('Cluster %s listening on port %s', cluster.worker.id, app.get('port'));
        });
    });
}

мы используем:руководитель для управления нашим узлом.Процесс JS, чтобы запустить их при загрузке и действовать в качестве сторожевого пса в случае сбоя процесса.

мы используем:nginx и в качестве обратного прокси-сервера для балансировки нагрузки между процесса, которые слушают разные порты

таким образом, каждый процесс изолирован от других.

например: Nginx прослушивает порт 80 и перенаправляет трафик на порты 8000-8003


Я довольно долго использовал PM2, но их цены дороги для моих нужд, поскольку у меня есть собственная аналитическая среда, и мне не нужна поддержка, поэтому я решил поэкспериментировать с альтернативами. Для моего случая, просто навсегда сделал трюк, очень простой на самом деле:

forever -m 5 app.js

еще один полезный пример

forever start app.js -p 8080