Узел создания процессов как количество ядер - PullRequest
0 голосов
/ 17 апреля 2020

С Node.JS документы:

Эти дочерние узлы все еще являются новыми экземплярами V8. Предположим, по крайней мере, 30 мс запуска и 10 Мб памяти для каждого нового узла. То есть вы не можете создать много тысяч из них.

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

var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  // Fork workers.
  for (var i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  cluster.on('death', function(worker) {
    console.log('worker ' + worker.pid + ' died');
    cluster.fork();
  });
} else {
  // Worker processes have a http server.
  http.Server(function(req, res) {
    res.writeHead(200);
    res.end("hello world\n");
  }).listen(8000);
}

Но если позволяет скажем, у нас есть 4 ядра, мы создаем 4 процесса + основной процесс, так что в общей сложности у нас будет 5 процессов, которые снова больше, чем ядра процессора.

Насколько это эффективно?

1 Ответ

1 голос
/ 17 апреля 2020

Как общий ответ, вы должны форкнуть столько процессов, сколько и number of CPUs - 1, так как вы должны оставить одно ядро ​​SO для управления другими процессами на вашем сервере (cron? Logrotate? Что угодно).

Более того, процессы, которые вы разветвляете, могут использовать один и тот же процессор, поскольку по умолчанию ОС Процессор управляется ОС. ( вот пример для его настройки и хороший ответ на stackoverflow .

Итак, это зависит в основном от того, что делает ваше приложение, поскольку разветвление не могло принести пользу все. Вилка для работы процессора с высокой интенсивностью (например, crypto или какого-либо блокирующего события l oop действия) получит выгоду от этой оптимизации.

Например, используя ваш скрипт и простой тест с

npx autocannon -c 100 -d 5 -p 10 localhost:8000/:

┌───────────┬────────┬────────┬─────────┬─────────┬─────────┬──────────┬────────┐
│ Stat      │ 1%     │ 2.5%   │ 50%     │ 97.5%   │ Avg     │ Stdev    │ Min    │
├───────────┼────────┼────────┼─────────┼─────────┼─────────┼──────────┼────────┤
│ Req/Sec   │ 46943  │ 46943  │ 71039   │ 79039   │ 68444.8 │ 11810.39 │ 46930  │
├───────────┼────────┼────────┼─────────┼─────────┼─────────┼──────────┼────────┤
│ Bytes/Sec │ 6.1 MB │ 6.1 MB │ 9.23 MB │ 10.3 MB │ 8.9 MB  │ 1.54 MB  │ 6.1 MB │
└───────────┴────────┴────────┴─────────┴─────────┴─────────┴──────────┴────────┘

Затем тот же сценарий автоматического сканирования конечной точки без вилки:

var http = require('http')

// Worker processes have a http server.
http.Server(function (req, res) {
  res.writeHead(200)
  res.end('hello world\n')
}).listen(8000)
┌───────────┬─────────┬─────────┬────────┬─────────┬─────────┬─────────┬─────────┐
│ Stat      │ 1%      │ 2.5%    │ 50%    │ 97.5%   │ Avg     │ Stdev   │ Min     │
├───────────┼─────────┼─────────┼────────┼─────────┼─────────┼─────────┼─────────┤
│ Req/Sec   │ 48063   │ 48063   │ 62303  │ 63167   │ 59632   │ 5807.42 │ 48040   │
├───────────┼─────────┼─────────┼────────┼─────────┼─────────┼─────────┼─────────┤
│ Bytes/Sec │ 6.25 MB │ 6.25 MB │ 8.1 MB │ 8.21 MB │ 7.75 MB │ 755 kB  │ 6.25 MB │
└───────────┴─────────┴─────────┴────────┴─────────┴─────────┴─────────┴─────────┘

Здесь без разветвление не намного медленнее !!

Но если мы изменим конечную точку с высокой загрузкой процессора:

http.Server(function (req, res) {
  res.writeHead(200)
  for (var i = 0; i < 999999; i++) {
    // cpu cycle waste
  }
  res.end('hello world\n')
}).listen(8000)

Мы получим без форка:

┌───────────┬────────┬────────┬────────┬────────┬────────┬─────────┬────────┐
│ Stat      │ 1%     │ 2.5%   │ 50%    │ 97.5%  │ Avg    │ Stdev   │ Min    │
├───────────┼────────┼────────┼────────┼────────┼────────┼─────────┼────────┤
│ Req/Sec   │ 1671   │ 1671   │ 1790   │ 1870   │ 1784.2 │ 76.02   │ 1671   │
├───────────┼────────┼────────┼────────┼────────┼────────┼─────────┼────────┤
│ Bytes/Sec │ 217 kB │ 217 kB │ 233 kB │ 243 kB │ 232 kB │ 9.88 kB │ 217 kB │
└───────────┴────────┴────────┴────────┴────────┴────────┴─────────┴────────┘

А затем с помощью форка + высокоинтенсивная работа процессора с большим улучшением !!

┌───────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┐
│ Stat      │ 1%      │ 2.5%    │ 50%     │ 97.5%   │ Avg     │ Stdev   │ Min     │
├───────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Req/Sec   │ 8575    │ 8575    │ 9423    │ 9823    │ 9324    │ 421.9   │ 8571    │
├───────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Bytes/Sec │ 1.12 MB │ 1.12 MB │ 1.22 MB │ 1.28 MB │ 1.21 MB │ 54.7 kB │ 1.11 MB │
└───────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┘

Так что я думаю, что вам не следует «предварительно оптимизировать» конечную точку HTTP, так как это может быть большой работой без усилий.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...