精华 Nodejs不同版本原生的cluster负载均衡测试
发布于 9 年前 作者 struCoder 6702 次浏览 最后一次编辑是 8 年前 来自 分享

===========2015-06-30更新=========

更新内容: window, linux, Mac os已经测试完

本文原始链接   代码我托管在github上了,文章最后有链接 Nodejs不同版本负载均衡测试

做这个测试的原因

之所以做这个测试是因为,昨天听到同事说nodejs在0.10* 版本中的负载均衡没有达到预期的效果,他也做了他的测试 刚好这几天我自己也不怎么的忙,所以就去官网看了看关于cluster相关的API,于是就有了下面的内容。

测试思路

  • fork出子进程创建http服务器
  • 主进程监听子进程的发来的消息进行统计
  • 主进程发起一定数量的http请求, 请求完后进行统计

测试平台

window: 8.1
linux: 14.04.2 Mac OS: 10

实现代码

文件结构

|--clusterMode.js
|--req.js

clusterMode.js代码

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

if (cluster.isMaster) {
	var workers = 0;
	var workerObj = {};
	var options = {
		hostname: 'localhost',
		port: 3050,
		path: '/',
		agent: false
	}

	console.log('master process start up...');
	for (var i = 0; i < cpus; i++) {
		cluster.fork();
	}

	Object.keys(cluster.workers).forEach(function(id) {
		cluster.workers[id].on('message', function(pid) {
			workerObj['process id:  ' + pid] += 1;
		});
	})

	cluster.on('listening', function(worker, address) {
		workerObj['process id:  ' + worker.process.pid] = 0;
		console.log('worker process id: ' + worker.process.pid);
	});

	cluster.on('exit', function(worker, code, signal) {
		console.log('worker: ' + worker.process.pid + ' died');
	});

	cluster.on('online', function(worker) {
		workers +=1;
		if (workers === cpus) {
			setTimeout(function() {
				var totalReq = 100;
				var selfReq = require('./req');
		    console.log('requesting');
		    selfReq(options, totalReq, function() {
		    	console.log('req end');
		    	console.log('waiting for result...');
		    	setTimeout(function() {
		    		console.log(workerObj);
		    	}, 2500);
		    });
			}, 2000);
		}
	});
} else {
	var server = http.createServer(function(req, res) {
		process.send(process.pid);
		res.end();
	});

	server.listen(3050);
}

req.js代码

var http = require('http');

module.exports = function(options, totalReq, cb) {
  var finishReq = 0;
  for(var i = 0; i < totalReq; i ++) {
    (function(j) {
      http.get(options, function(res) {
        finishReq += 1;
        if (finishReq === totalReq && typeof cb === 'function') {
          cb();
        }
      }).on('error', function(e) {
        console.log('error: ',e);
      });
    })(i);
  }
}

windows测试结果

第一张图为node v0.10*版本测试结果 1.png

第二张图为node v0.11*版本测试结果 2.png

第三张图为node v0.12*版本测试结果 3.png

Linux测试结果

第一张图为node v0.10版本测试结果 linux.png
第二张图为node v0.11
版本测试结果 linux-11.png 第三张图为node v0.12*版本测试结果 linux-12.png

Mac OS 测试结果

第一张图为node v0.10版本测试结果 macos-10.png 第二张图为node v0.11版本测试结果 macos-11.png 第三张图为node v0.12*版本测试结果 macos-12.png

测试总结

从这三个平台的测试结果可以看出,在windows平台上只有nodejs在v0.12后才达到了所 预期的负载均衡, 其余版本都不怎么理想。 而在linux和mac上,在nodejs v0.11版本就已经达到了负载均衡.

测试代码

GitHub

最后

本文为原创,允许转载,但请保留此链接 http://www.itodo.me/u/p/detail/gxjo9TBvenx8q8NkB

文章文字叙述或者代码有不正确的地方欢迎指正. :)

9 回复

windows 上的测试结果,对于绝大多数部署在 linux 服务器上的程序来说。。是否有借鉴意义? 使用 cluster 模式的时候,pm2 完全不懂怎么正确的进行负载均衡,pm2 也是忠实地在使用 cluster 而已。

@alsotang 哈哈,不好意思,这几天忙着其它事,不同平台我已经测试了一下。文章已经更新了:)

@alsotang “pm2 完全不懂怎么正确的进行负载均衡”这句话该怎么理解,因为我也使用pm2部署,但是由于对cluster模块使用不太熟悉,所以使用的是fork模式的多实例。不过对于上面那句话比较在意。

win 1.x负载均衡效果不好,原因找到了吗?

@haozxuan pm2 之前是有 fork 和 cluster 模式两种。cluster 模式下,它使用的就是 node 的 cluster 模块。至于 fork 模式,我不懂当时它是怎么做负载均衡的,不过现在随着 cluster 模块的稳定,pm2 已经不推荐使用 fork 模式了。

@alsotang "pm2 已经不推荐使用 fork 模式了"哪里有相关描述吗?

@haozxuan 【不推荐】这个表述是我的失误,应该也没有不推荐吧,只是很多时候 cluster 特性更多。

  1. pm2 在 node 0.10 的时候,开启多个进程默认是 fork 模式的。0.12 之后,默认就是 cluster 模式,只有单进程才 fork 模式。
  2. fork 模式没法使用 pm2 reload,让程序不中断服务地重启。fork 只能 pm2 restart

@alsotang 恩恩。随着cluster模块(node4.0)标注为稳定,的确有很多优势,是要将无状态服务转变为多核模式了。

@haozxuan 。。。。。。。。就算 fork 也不支持有状态服务啊。单核才适用

回到顶部