【问题标题】:In Node js, what happens if a new request arrives and event loop is already busy processing a request?在 Node js 中,如果一个新的请求到达并且事件循环已经忙于处理一个请求会发生什么?
【发布时间】:2020-06-26 21:09:52
【问题描述】:

我有这个文件名为index.js:

const express = require('express')
const app = express()
const port = 3000

app.get('/home', (req, res) => {
    res.send('Hello World!')
})

app.get('/route1', (req, res) => {
    var num = 0;
    for(var i=0; i<1000000; i++) {
        num = num+1;
        console.log(num);
    }
    res.send('This is Route1 '+ num)
})

app.listen(port, () => console.log(`Example app listening on port ${port}!`))

我首先调用端点/route1,然后立即调用端点/home/route1 具有 for loop 并需要一些时间才能完成,然后 /home 运行并完成。我的问题是,当应用程序忙于处理 /route1 时,如果节点 js 是单线程的,那么对 /home 的请求是如何处理的?

【问题讨论】:

    标签: node.js express


    【解决方案1】:

    传入的请求将在 nodejs 事件队列中排队,直到 nodejs 有机会处理下一个事件(当您的长时间运行的事件处理程序完成时)。

    由于 nodejs 是一个事件驱动的系统,它从事件队列中获取一个事件,运行该事件的回调直到完成,然后获取下一个事件,运行它直到完成等等。 nodejs 的内部将等待运行的东西添加到事件队列中,以便它们排队等待事件循环的下一个循环。

    根据 nodejs 网络的内部机制,传入的请求可能会在操作系统中排队一段时间,然后移动到事件队列中,直到 nodejs 有机会为该事件提供服务。

    我的问题是,当应用程序忙于处理 /route1 时,给 /home 的请求是如何处理的,因为 node js 是单线程的?

    请记住,node.js 将您的 Javascript 作为单线程运行(尽管我们现在有 Worker Threads 如果您愿意),但它确实在内部使用线程来管理文件 I/O 和一些其他类型的异步操作。不过,它不需要用于网络的线程。这是通过操作系统的实际异步接口进行管理的。

    【讨论】:

      【解决方案2】:

      Nodejs 有事件循环,事件循环允许 nodejs 执行非阻塞 I/O 操作。每个事件循环迭代称为一个滴答。事件循环有不同的阶段。

      首先是timer phase,因为您的脚本事件循环中没有计时器,所以会进一步检查 I/O 脚本。

      1. 当您点击路由/route1 时,Node JS Web 服务器内部会维护一个有限线程池来为客户端请求提供服务。它将被放置在 FIFO 队列中,然后事件循环将进一步到达polling phase

      2. 轮询阶段将等待挂起的 I/O,即路由 /route1。 Even Loop 检查任何客户端请求是否放置在事件队列中。如果否,则无限期等待传入请求。

      3. 同时,下一个 I/O 脚本到达 FIFO 队列,即路由 /home

      FIFO的意思是先进先出。因此首先/route1 将得到执行路由/home

      您可以在下面通过图表看到这一点。

      Node.js 应用程序在单线程上运行,并且事件循环也在同一线程上运行

      Node.js 内部使用 libuv 库,该库负责处理与操作系统相关的任务,例如基于异步 I/O 的操作系统、网络、并发。

      More info

      【讨论】:

        【解决方案3】:

        Node 有一个内部线程池,当发送阻塞(io 或内存或网络)请求时,会从该线程池中分配一个线程。如果不是,则处理该请求并将其原样发回。如果线程池已满,则请求在队列中等待。请参考How, in general, does Node.js handle 10,000 concurrent requests? 以获得更清晰的答案。

        【讨论】:

          猜你喜欢
          • 2017-11-28
          • 2022-07-20
          • 2018-07-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-01-01
          • 2017-03-24
          • 2021-08-12
          相关资源
          最近更新 更多