我为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))
}
@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))
}
答案 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秒钟,直到循环结束。