Как увеличить пропускную способность на сервере NodeJS с помощью кластера?
у меня есть сервер NodeJS (Express), и я распространяю запросы на несколько процессоров, используя пример кластерного модуля на сайте nodeJs.
if (cluster.isMaster) {
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
};
cluster.on('exit', function(worker, code, signal) {
console.log('worker ' + worker.process.pid + ' died');
cluster.fork();
});
} else {
server.listen(app.get('port'), function(){
console.log('HTTP server on port ' + app.get('port') + ' - running as ' + app.settings.env);
});
// setup socket.io communication
io.sockets.on('connection', require('./app/sockets'));
io.sockets.on('connection', require('./app/downloadSockets'));
}
проблема в том, что бенчмарк из siege показывает мне, что нет увеличения количества попаданий. Это выход осады:
$ siege -c100 192.168.111.1:42424 -t10S
** SIEGE 3.0.5
** Preparing 100 concurrent users for battle.
The server is now under siege...
Lifting the server siege... done.
Transactions: 1892 hits
Availability: 100.00 %
Elapsed time: 10.01 secs
Data transferred: 9.36 MB
Response time: 0.01 secs
Transaction rate: 189.01 trans/sec
Throughput: 0.93 MB/sec
Concurrency: 1.58
Successful transactions: 1892
Failed transactions: 0
Longest transaction: 0.05
Shortest transaction: 0.00
После Кластеризации :
$ siege -c100 192.168.111.1:42424 -t10S
** SIEGE 3.0.5
** Preparing 100 concurrent users for battle.
The server is now under siege...
Lifting the server siege... done.
Transactions: 1884 hits
Availability: 100.00 %
Elapsed time: 9.52 secs
Data transferred: 9.32 MB
Response time: 0.01 secs
Transaction rate: 197.90 trans/sec
Throughput: 0.98 MB/sec
Concurrency: 1.72
Successful transactions: 1884
Failed transactions: 0
Longest transaction: 0.07
Shortest transaction: 0.00
означает ли это, что мой сервер уже получает максимальную пропускную способность с одним сервером, вероятно, потому, что его локальная машина или возможно, он не может получить 4 процессора, так как слишком много процессов работает, я не уверен.
как использовать кластерный модуль для увеличения throghput и почему мой текущий код не пройти ? Также я проверил, что он действительно создает 4 экземпляра сервера i.e кластер.вилка работает. Любые советы были бы очень полезны.
2 ответов
эффект достигается за счет кластеризации или роста параллельных запросов (попробуйте увеличить число одновременных пользователей до 300-400). Или задачи, которые дают серьезную нагрузку. Проведем более интересный тест: загрузим файл размером около 1 МБ, плюс сделаем задержку 5 мсек и 50 мсек для эмуляции сложных операций. Для четырехъядерного процессора при локальном тестировании будет следующим (соответственно для обычного и кластерного):
$ siege -c100 http://localhost/images/image.jpg -t10S
нормальный режим (5 мсек задержка):
Lifting the server siege... done.
Transactions: 1170 hits
Availability: 100.00 %
Elapsed time: 9.10 secs
Data transferred: 800.79 MB
Response time: 0.27 secs
Transaction rate: 128.57 trans/sec
Throughput: 88.00 MB/sec
Concurrency: 34.84
Successful transactions: 1170
Failed transactions: 0
Longest transaction: 0.95
Shortest transaction: 0.01
режим кластера (задержка 5 мс):
Lifting the server siege... done.
Transactions: 1596 hits
Availability: 100.00 %
Elapsed time: 9.04 secs
Data transferred: 1092.36 MB
Response time: 0.06 secs
Transaction rate: 176.55 trans/sec
Throughput: 120.84 MB/sec
Concurrency: 9.81
Successful transactions: 1596
Failed transactions: 0
Longest transaction: 0.33
Shortest transaction: 0.00
нормальный режим (задержка 50 мс):
Lifting the server siege... done.
Transactions: 100 hits
Availability: 100.00 %
Elapsed time: 9.63 secs
Data transferred: 68.44 MB
Response time: 5.51 secs
Transaction rate: 10.38 trans/sec
Throughput: 7.11 MB/sec
Concurrency: 57.18
Successful transactions: 100
Failed transactions: 0
Longest transaction: 7.77
Shortest transaction: 5.14
режим кластера (задержка 50 мсек):
Lifting the server siege... done.
Transactions: 614 hits
Availability: 100.00 %
Elapsed time: 9.24 secs
Data transferred: 420.25 MB
Response time: 0.90 secs
Transaction rate: 66.45 trans/sec
Throughput: 45.48 MB/sec
Concurrency: 59.59
Successful transactions: 614
Failed transactions: 0
Longest transaction: 1.50
Shortest transaction: 0.50
вы на самом деле ничего не делаете в своем примере. Подключитесь к mysql и запустите тяжелый запрос или сделайте http-запрос, который занимает несколько секунд. Вы замечаете, что в конечном итоге вы будете кодировать что-то (или использовать стороннюю библиотеку), которая заблокирует цикл событий. Это когда кластеризация будет важна, так как вы по существу будете иметь цикл событий для каждого процессора. Если один запрос медленный, и цикл событий должен ждать его, он не остановит новые запросы, которые поражают ваш API / application.
кроме того, вы можете прочитать о пуле соединений и, в частности, generic-pool на npm, если вы планируете использовать или подключаться к базе данных или получать внешние ресурсы.