node.js中的群集无法正常工作。只有一名工人总是在回应

cJ_*_*cJ_ 5 javascript node.js

我在node.js中练习集群,我有两个核心CPU。我创建了两个工作程序,每个工作程序都运行一个简单的http服务器。服务器响应回调将阻塞5秒钟,以向其他工作人员发出下一个请求。为了验证工作程序是否并行工作,我在Firefox中打开了多个标签,并刷新了每个标签。问题始终是(99%),只有一名工作人员正在响应通过刷新选项卡发出的请求。一名工作人员仅服务于一个请求,其他所有请求均被阻止,直到该工作人员完成为止。我的代码在这里CODE:

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);
}
Run Code Online (Sandbox Code Playgroud)

输出:

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
Run Code Online (Sandbox Code Playgroud)

我注意到一件事。如果我强制重新加载(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
Run Code Online (Sandbox Code Playgroud)

我很困惑正常刷新(f5)和强制重载(ctrl + f5)在这里发生的情况。帮我弄清楚...!

Box*_*cks 6

表面节点聚类上的 TIL 似乎没有做它所说的(至少对我而言)。

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

似乎一旦经理将请求交给工作人员,它就不知道/不关心工作人员的阻塞。它只知道管道中只有一个请求,并且不需要将该请求提供给第一个工人以外的任何人,因为据经理所知,他有空。


Mik*_*e S 2

while响应代码中的循环可能会导致一些严重的问题。setTimeout如果你想模拟长时间运行的请求, 你应该使用there。

请为您的员工尝试以下操作:

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);
Run Code Online (Sandbox Code Playgroud)

话虽如此,@dandavis 在评论中所说的是正确的:cluster不进行循环负载平衡,因此,只要Worker 1可用于请求,它就会处理它们。像我建议的那样使用setTimeout实际上会让您的工作人员Worker 1容易处理请求,因此如果您只是从浏览器手动访问服务器,您可能只会看到处理请求。您可能需要某种负载测试脚本来查看两个工作人员处理请求的情况。

至于您在F5CTRL-F5之间看到的差异,我最好的猜测是您的浏览器保持与服务器的连接处于活动状态,因此,当您仅使用F5时,它使用相同的连接,该连接将始终转到相同的连接工人。当您使用CTRL-F5时,它实际上会关闭之前的连接,因此可以在下一个请求时连接到任一工作人员。