Nodejs 事件循环如何处理池阶段和检查阶段,同时处理数千个传入的 http 请求

问题描述 投票:0回答:1

想象一下我的Web应用程序如此受欢迎,我的NodeJS Web服务器每秒处理数千个请求,每个请求回调调用setImmediate(cb),我不认为setImmediate回调有机会运行,因为事件循环没有机会去到(检查阶段)setImmediate回调,因为池阶段每秒有数千个请求回调,是真的吗? 我正在尝试这样刺激

这是我的客户端 JavaScript 代码,我正在向服务器发送 50 个请求:

for(let i = 1; i <= 50; i++) {
const fetchData = async () => {
    const data = await fetch('http://127.0.0.1:3000');
    console.log(data + ' ' + i);
}
fetchData()

}

这是我的服务器端 JavaScript 代码:

const express = require('express');
const fs = require('fs');
const cors = require('cors');
const app = express();
app.use(cors())
let num = 0;
app.get('/', (req, res) => {
    num = num + 1;
    console.log(`the request number is: ${num}`);
    // for(let i = 1; i <= 20000; i++) {
    //     console.log(i)
    // }
    // fs.readFile(`${__dirname}/text.txt`, 'utf-8', (err, data) => {
    //     console.log(`${data} ${num}`)
    // })
    res.status(200).send('hello from the server');
    // setTimeout(() => console.log('hello i am from timeout ' + num), 0)
    setImmediate(() => {
        console.log('hello i am from setImmediate ' + num )
    })
    // process.nextTick(() => {
    //     console.log('hello i am from nextTick ' + num )
    // })
    
})
app.listen(3000, () => {
    console.log('server is listening')
})

Nodejs 文档说,当事件循环进入池阶段时,它会执行回调队列中的所有回调,当回调队列为空时,它会移动到 checkphase 并执行 setImmediate 的回调,但在我的示例中,我从前端发送 50 个请求,应该有 50 个请求池阶段的回调,那么为什么它没有完成所有 50 个请求回调,然后执行 setImmediate 的回调,而是完成一个请求回调并执行 setImmediate 的回调,然后执行第二个请求回调,然后执行 setImmediate 的回调。 我附上了输出的图像

node.js pool event-loop nodejs-server setimmediate
1个回答
0
投票

我认为您对 Node.js 中的事件循环如何工作的理解存在误解。在事件循环的每个阶段,都有一个称为计时器的东西,当特定的事件循环阶段开始执行时,它就会被触发。一旦计时器运行到零,该阶段的执行就会停止,并转移到下一个阶段 - 这样其他阶段就不会出现饥饿。

我只是想在这里给你一个非常模糊的例子。

  1. 假设池阶段执行已开始
  2. Nodejs 启动一次,假设为 500 毫秒
  3. 事件循环将自动进入下一阶段 - 当所有任务在池阶段完成或 500 毫秒到期时。
  4. 现在setImmediate会自动执行。

要记住的一件事是 Nodejs 事件循环概念中根本不存在饥饿。

如果应用程序如此出名,请在进程的每个线程中运行节点。给工人分配任务。阅读这些概念,会有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.