Nodejs cluster测试
Nodejs cluster测试
在双核上开两个worker,阻塞一个worker后,其他worker也被阻塞了。开10个worker也一样,是我cpu核心太少吗?还是本来就这样。
连续发送两个请求,只有一个核是100%,并且从输出看只有一个节点在工作:
A worker with #1 is now connected to 0.0.0.0:8000
A worker with #2 is now connected to 0.0.0.0:8000
Worker #1 has a request
Worker #1 make a response
Time: 5000ms
Worker #1 has a request
Worker #1 make a response
Time: 5001ms
脚本文件: var cluster = require(‘cluster’); var http = require(‘http’); var numCPUs = require(‘os’).cpus().length;
if (cluster.isMaster) {
require('os').cpus().forEach(function(){
cluster.fork();
});
cluster.on('exit', function(worker, code, signal) {
console.log('worker ' + worker.process.pid + ' died');
});
cluster.on('listening', function(worker, address) {
console.log("A worker with #"+worker.id+" is now connected to " +
address.address +
":" + address.port);
});
} else {
http.createServer(function(req, res) {
console.log('Worker #' + cluster.worker.id + ' has a request');
res.writeHead(200);
console.time('Time');
function sleep(milliSeconds) {
var startTime = new Date().getTime();
while (new Date().getTime() < startTime + milliSeconds);
}
sleep(5000);
res.end("hello world\n");
console.log('Worker #' + cluster.worker.id + ' make a response');
console.timeEnd('Time');
}).listen(8000);
}
Node.js Cluster 测试
在使用 Node.js 的 cluster
模块时,你可能会遇到一些困惑,特别是在处理多核 CPU 和并发请求时。你提到的情况可能是由于某些原因导致多个 Worker 实际上没有并行处理请求。让我们通过分析你的代码和问题来理解可能的原因。
问题描述
你在双核或四核 CPU 上启动了多个 Worker(例如两个或十个),但只看到一个 Worker 在处理请求。你怀疑这是否是因为 CPU 核心数量不够,或者是因为这是 Node.js 的正常行为。
示例代码分析
首先,我们来看一下你的代码:
var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
// 创建与 CPU 核心数量相同的 Worker
require('os').cpus().forEach(function() {
cluster.fork();
});
// 监听 Worker 启动事件
cluster.on('exit', function(worker, code, signal) {
console.log('worker ' + worker.process.pid + ' died');
});
// 监听 Worker 连接事件
cluster.on('listening', function(worker, address) {
console.log("A worker with #" + worker.id + " is now connected to " +
address.address + ":" + address.port);
});
} else {
// Worker 端的 HTTP 服务器
http.createServer(function(req, res) {
console.log('Worker #' + cluster.worker.id + ' has a request');
res.writeHead(200);
console.time('Time');
function sleep(milliSeconds) {
var startTime = new Date().getTime();
while (new Date().getTime() < startTime + milliSeconds);
}
sleep(5000); // 模拟长时间运行的任务
res.end("hello world\n");
console.log('Worker #' + cluster.worker.id + ' make a response');
console.timeEnd('Time');
}).listen(8000);
}
问题分析
-
单线程模型:尽管你创建了多个 Worker,每个 Worker 实际上仍然是单线程的。这意味着每个 Worker 只能处理一个请求,直到当前请求处理完毕。因此,即使你有多个 Worker,如果其中一个 Worker 正在处理一个长时间运行的任务(如
sleep(5000)
),其他请求将被阻塞。 -
CPU 核心限制:虽然你创建了多个 Worker,但如果你的长时间运行任务占用了 CPU 资源,其他 Worker 可能无法有效利用空闲的 CPU 核心。
解决方案
为了实现真正的并发处理,可以考虑以下几点:
-
异步处理:避免使用阻塞操作(如
sleep
函数)。改用异步方法(如setTimeout
或第三方库如async
)来处理长时间运行的任务。setTimeout(() => { res.end("hello world\n"); console.log('Worker #' + cluster.worker.id + ' make a response'); console.timeEnd('Time'); }, 5000);
-
负载均衡:确保每个 Worker 都能够有效地处理请求。你可以通过监控和调整 Worker 数量来优化性能。
-
非阻塞 I/O:Node.js 本身就是基于事件驱动和非阻塞 I/O 的,所以尽量避免阻塞操作。
通过这些改进,你应该能够更好地利用多核 CPU 并实现真正的并发处理。
关注
我的四核,两个核用到了。
C:\dev\test\node-module\cluster>node test.js
cpu#:4
cpu#:4
A worker with #1 is now connected to 0.0.0.0:8000
cpu#:4
A worker with #4 is now connected to 0.0.0.0:8000
cpu#:4
A worker with #3 is now connected to 0.0.0.0:8000
cpu#:4
A worker with #2 is now connected to 0.0.0.0:8000
Worker #2 has a request
Worker #2 make a response
Time: 5001ms
Worker #2 has a request
Worker #2 make a response
Time: 5000ms
Worker #2 has a request
Worker #2 make a response
Time: 5000ms
Worker #2 has a request
Worker #3 has a request
Worker #2 make a response
Time: 5000ms
Worker #2 has a request
Worker #3 make a response
Time: 5001ms
Worker #3 has a request
Worker #2 make a response
Time: 5000ms
Worker #2 has a request
Worker #3 make a response
Time: 5000ms
Worker #3 has a request
Worker #2 make a response
Time: 5000ms
请参考 http://www.cnblogs.com/tingshuo/archive/2013/01/17/2864280.html
cluster是在并发高的情况下才会充分利用多核
其实,是我测试方式不对
cluster 的负载均衡做的不好
cluster在window下是不能多核负载均衡,在linux下才会
cluster在node v0.11之前的版本,负载都十分不均衡,目前看来v0.11的 cluster 已经修复了这个问题,期待0.12的稳定版早日release吧…