节点始终使用相同的群集

时间:2019-01-01 12:18:48

标签: node.js

我为cpu的每个线程创建了一个集群,并为每个请求等待5秒以响应,并打开了chrome的几个标签页并发出了请求,但所有这些请求都由同一个集群处理,并且是同步进行的,在按住第一个请求5秒钟后,它开始处理第二个请求,依此类推。

const cluster = require('cluster')
const numCPUs = require('os').cpus().length;

if(cluster.isMaster) {

for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

   cluster.on('exit', (worker, code, signal) => {
    console.log(`Worker ${worker.process.pid} died with code: ${code}, and         
signal: ${signal}`);
    console.log('Starting a new worker');
    cluster.fork();
  });

} else {

const express = require('express')
const app = express();

app.get('/', (req, res) => {
setTimeout(()=>{
    console.log('worker response id: ' + cluster.worker.id)
    res.status(200).end() 
}, 5000)
})
app.listen(3000, ()=>   console.log('Listening with worker',         
cluster.worker.id))

}

enter image description here

@Edit ----提起后的代码------

它现在可以工作,但是只有两次,您如何在图像上看到图像,另一次,该过程是同步的,仅使用一个群集,一次使用其他群集,我该如何更好地控制它?

const cluster = require('cluster')
const numCPUs = require('os').cpus().length;

if(cluster.isMaster) {

for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

   cluster.on('exit', (worker, code, signal) => {
    console.log(`Worker ${worker.process.pid} died with code: ${code}, and         
signal: ${signal}`);
    console.log('Starting a new worker');
    cluster.fork();
  });

} else {

const express = require('express')
const app = express();

function sleepSync(ms) {
    let targetTime = Date.now() + ms;
    while (Date.now() < targetTime);
}

app.get('/', (req, res) => {
    sleepSync(5000)
    console.log('worker response id: ' + cluster.worker.id)
    res.status(200).end() 
})
app.listen(3000, ()=>   console.log('Listening with worker', cluster.worker.id))

}

enter image description here

2 个答案:

答案 0 :(得分:2)

执行setTimeout花费微秒。超时不是一个繁忙的等待。在您的工人等待时,它可以免费用于其他任务。因此它将占用额外的请求,直到5秒钟连续用完为止。这是通过节点的Event Loop实现的。

更多原始的服务器实现也使用这种技术来实现并行性的概念。

为了发现差异,请尝试创建一个繁忙的等待(可能如下所示),并使用它代替setTimeout

function sleepSync(ms) {
    let targetTime = Date.now() + ms;
    while (Date.now() < targetTime);
}

答案 1 :(得分:1)

您还可以使用async / await来避免繁忙的等待和不必要地将一个CPU内核固定5秒钟:

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));

app.get('/', async (req, res) => {
    await sleep(5000);
    console.log('worker response id: ' + cluster.worker.id)
    res.status(200).end() 
});

要了解繁忙等待为什么不好的原因,请在应用程序循环运行这5秒钟时运行top,并查看您的CPU核心之一处于100%状态。替换为上面的代码,以确认CPU不再受到影响。

当您调用await时,Node.js知道它必须暂停函数执行,直到来自sleep()的承诺得以解决。同时,它还可以运行其他内容:其他计时器,其他传入的HTTP请求等。

Node.js是单线程的,因此,如果您忙于等待事情,Node.js将无法运行其他任何程序,并且您的程序会被双手紧紧地停顿5秒钟,直到循环结束。