我在node.js中练习集群我有两个核心CPU。我创建了两个worker,每个worker都运行一个简单的http服务器。服务器响应回调将阻塞5秒,以便向其他工作人员发出下一个请求。为了验证工作者是否并行工作,我在Firefox中打开了多个选项卡并刷新了每个选项卡。问题始终是(99%)只有一个工作人员正在响应刷新标签所做的请求。一名工作人员只提供一个请求,并且在该工作人员完成之前阻止所有其他请求。我的代码在这里 代码:
var cluster = require('cluster');
var http = require('http');
if (cluster.isMaster) {
var cpus = require('os').cpus().length;
console.log('No of cpus:' + cpus);
console.log(require('os').cpus());
for (var i = 0; i < cpus; i++) {
cluster.fork();
}
cluster.on('fork', function(worker) {
console.log('worker:' + worker.id + " is forked");
});
cluster.on('online', function(worker) {
console.log('worker:' + worker.id + " is online");
});
cluster.on('listening', function(worker) {
console.log('worker:' + worker.id + " is listening");
});
cluster.on('disconnect', function(worker) {
console.log('worker:' + worker.id + " is disconnected");
});
cluster.on('exit', function(worker) {
console.log('worker:' + worker.id + " is dead");
});
} else {
http.createServer(function(req, res) {
console.log('worker:' + cluster.worker.id + " going to send response ");
res.writeHead(200);
res.end("hello world. worker: " + cluster.worker.id);
var stop = new Date().getTime();
while (new Date().getTime() < stop + 5000) {;
}
}).listen(8000);
}
输出:
20 Aug 00:36:11 - [nodemon] restarting due to changes...
20 Aug 00:36:12 - [nodemon] starting `node cluster.js`
No of cpus:2
[ { model: 'Intel(R) Core(TM)2 Duo CPU E4500 @ 2.20GHz',
speed: 2200,
times: { user: 2264671, nice: 0, sys: 698343, idle: 5965109, irq: 98812 } },
{ model: 'Intel(R) Core(TM)2 Duo CPU E4500 @ 2.20GHz',
speed: 2200,
times: { user: 2466000, nice: 0, sys: 502562, idle: 5959203, irq: 4609 } } ]
worker:1 is forked
worker:2 is forked
worker:2 is online
worker:1 is online
worker:2 is listening
worker:1 is listening
worker:1 going to send response
worker:1 going to send response
worker:1 going to send response
worker:1 going to send response
worker:1 going to send response
worker:1 going to send response
worker:1 going to send response
worker:1 going to send response
worker:1 going to send response
worker:1 going to send response
worker:1 going to send response
worker:1 going to send response
worker:1 going to send response
worker:1 going to send response
worker:1 going to send response
worker:1 going to send response
worker:1 going to send response
worker:1 going to send response
worker:1 going to send response
worker:1 going to send response
我注意到了一件事。如果我强制重新加载(ctrl + f5)选项卡,那么两个工作人员都会一个接一个地响应。 输出:
worker:1 going to send response
worker:2 going to send response
worker:1 going to send response
worker:2 going to send response
worker:1 going to send response
worker:2 going to send response
worker:1 going to send response
worker:2 going to send response
worker:1 going to send response
worker:2 going to send response
worker:1 going to send response
worker:2 going to send response
worker:1 going to send response
worker:2 going to send response
worker:1 going to send response
worker:2 going to send response
worker:1 going to send response
worker:2 going to send response
worker:1 going to send response
worker:2 going to send response
worker:1 going to send response
worker:2 going to send response
worker:2 going to send response
worker:1 going to send response
worker:2 going to send response
worker:1 going to send response
worker:2 going to send response
worker:1 going to send response
worker:2 going to send response
我很困惑这里发生的正常刷新(f5)和强制重装(ctrl + f5)。帮我解决一下......!
答案 0 :(得分:4)
表面节点群集上的TIL似乎没有像它所说的那样做(至少对我而言)。
我遇到了同样的情况,当我从浏览器同步生成请求时,观察同一个工作进程总是被请求。我的一位同事用提琴手一次重播约20个请求。当所有这些请求以非常快的速度到达服务器时,比集群管理器更快地将它们传递给工作人员(我猜),那么您将看到通过请求调用其他工作程序。
似乎一旦经理将请求移交给工人,它就不知道/关心工人阻塞。它只知道管道中只有一个请求,并且没有必要将该请求提供给第一个工作人员以外的任何人,因为就经理所知,他是可用的。
答案 1 :(得分:0)
您的响应代码中的while
循环可能会导致一些严重问题。如果要模拟长时间运行的请求,则应该在那里使用setTimeout
。
请为您的员工尝试此操作:
http.createServer(function(req, res) {
console.log('worker:' + cluster.worker.id + " going to send response ");
setTimeout(function() {
res.writeHead(200);
res.end("hello world. worker: " + cluster.worker.id);
}, 5000);
}).listen(8000);
话虽如此,@ dandavis在评论中说的是真的:cluster
不进行循环负载平衡,因此,只要Worker 1
可用于请求,它就会处理它们。像我建议的那样使用setTimeout
实际上会让您的工作人员更多可以处理请求,因此您可能只会看到Worker 1
处理请求#39;只是从浏览器手动点击服务器。您可能需要某种负载测试脚本来查看两个工作人员处理请求。
至于你在 F5 和 CTRL-F5 之间看到的差异,我最好的猜测是你的浏览器保持与服务器的连接,所以,当您只使用 F5 时,它使用相同的连接,该连接将始终发送给同一个工作人员。当您使用 CTRL-F5 时,它实际上关闭了之前的连接,因此可以在下次请求时连接到任一工作人员。