node.js中的集群不起作用。 只有一个工作人员总是回应

我正在练习node.js中的集群我有一个两个核心的CPU。 我创build了两个worker,每个worker都运行一个简单的http服务器。 服务器响应callback将阻塞5秒,以向其他工作人员发送下一个请求。 为了validation工作人员并行工作,我在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); } 

OUTPUT:

 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)选项卡,那么这两个工作人员正在响应一个接一个。 OUTPUT:

 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)发生了什么。 帮我弄清楚…!

TIL表面上的节点集群似乎没有做它所做的事情(至less对我来说)。

我和你的情况是一样的,观察同一个工作进程,当我从浏览器同步产生这个进程时,总是收到一个请求。 我的一个同事使用提琴手一次重放〜20个请求。 当所有这些请求都以非常快的速度到达服务器时,比集群pipe理器可以将它们传递给工作人员更快(我猜测),那么您将看到额外的工作人员被请求调用。

看起来,一旦pipe理者把请求交给工人,它就不知道/关心工人阻塞。 它只知道pipe道中只有一个请求,并且不需要向第一个工人以外的任何人提出这个请求,因为就经理所知,他是可用的。

你在响应代码中的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可用于请求,它就会处理它们。 像我build议的那样使用setTimeout实际上会让你的工作者容易处理请求,所以如果你只是通过浏览器手动地访问服务器,你很可能只会看到Worker 1处理请求。 您可能需要某种加载testing脚本来查看这两个工作人员处理请求。

至于你在F5CTRL-F5之间所看到的差异,我最好的猜测是你的浏览器保持与服务器的连接,所以当你使用F5时 ,它使用相同的连接,工人。 当你使用CTRL-F5时,它实际上closures了之前的连接,因此可以在下一个请求中连接到任一工作者。