NodeJS/Express 如何同时处理多个 CPU 绑定请求

Posted

技术标签:

【中文标题】NodeJS/Express 如何同时处理多个 CPU 绑定请求【英文标题】:How does NodeJS/Express handle multiple CPU bound requests at the same time 【发布时间】:2021-04-12 13:56:06 【问题描述】:
const run = ()=> 
console.log("Begin")
for(var i=0;i<10000000000;i++)

console.log("End")

const express = require('express')
const app = express()
const port = 3000
app.get('/', (req, res) => 
 run()
 res.send('Hello World!')
)
app.listen(port, () => 
 console.log(`Example app listening at http://localhost:$port`)
)

这是一个最小的节点应用程序,在每个请求上,它都会调用循环(5-10 秒)并返回响应。 我尝试了两次,几乎同时,到达第二个的请求必须等待第一个完全完成。

from flask import Flask
def run():
    print("Begin")
    for i in range(1000000000):
        pass
    print("End")
app = Flask(__name__)
@app.route('/')
def hello_world():
    run()
    return 'Hello, World!'
if __name__ == '__main__':
    app.run()

这是一个做同样事情的最小烧瓶应用程序,该方法大约需要 10 秒,但是当我两次点击 API 时,“Begin”被打印了两次(2 Threads)。

我确定我在 Node 应用程序中遗漏了一些东西,这使我无法为每个请求提供自己的线程,因为涉及 CPU 绑定操作。我知道 NodeJS 在单线程事件循环上运行,但我确信当它服务多个请求时,应该涉及一些线程。我错过了什么?

【问题讨论】:

【参考方案1】:

Node.js虽然是单线程,但也提供了多种处理CPU绑定任务的形式。

首先,您可以为您的服务器创建一个cluster 进程,这听起来可能很复杂,但大部分工作已经为您完成,因为进程之间的通信甚至请求分发给子进程来处理。您还可以将特定任务与多个worker threads 一起划分。这实际上取决于您要解决的问题,两种方法各有优缺点。

【讨论】:

这很有趣,所以您需要一些手动干预来处理并发请求,而其他框架是开箱即用的多线程? 事实上,我展示的一切都是 Node.js 的特性。在 Python 上,您使用的是 Flask,这是一个基于 Python 自身语言功能的微型框架。【参考方案2】:

它不会同时处理多个同步的 cpu 绑定任务。单个线程的含义正是它听起来的样子。如果您有一段代码正在执行,则在它完成或通过执行某种异步调用让给另一段代码之前不会执行其他代码。有关更多详细信息,有很多关于该主题的文章。 https://developer.mozilla.org/en-US/docs/Web/javascript/EventLoop

【讨论】:

但是当您有 100 个请求同时访问您的服务器时,这将如何有效呢? 如果您正在执行 CPU 密集型任务,那将是绝对可怕的。但是,Web 服务器所做的大部分工作都是 IO。它们与数据库通信,或者向其他服务发出请求。他们还可以将工作分包给同一个盒子上的其他进程。根据我的经验,除了图像处理等罕见情况之外,很少有 Web 服务提供真正的 cpu 绑定服务。这些可以很容易地被外包给更合适的语言/服务。此外,计算机在 cpu 任务上的速度也快得离谱。向他们提供数据可能是真正的瓶颈。 你确定吗?看看这个:medium.com/@sararavi14/node-js-threading-model-badf7bb5fffa 本地调用和节点虚拟机被允许做任何他们想做的事情。在幕后,这意味着可能涉及多个线程。但是,Javascript 的实际执行是在单个线程中完成的。听起来您没有阅读我链接的文档。您应该阅读更多内容,并在以后提出更具体的问题。

以上是关于NodeJS/Express 如何同时处理多个 CPU 绑定请求的主要内容,如果未能解决你的问题,请参考以下文章

如何从不同的上传点在同一页面上上传多个文件。使用 nodejs express-fileupload

如何使用 nodejs / express 上传和读取文件

nodejs / express:如何使用数据发布到外部表单?

如何将 React + NodeJS Express 应用程序部署到 AWS?

使用异步和请求包(NodeJS / Express)进行多个 API 调用

在nodejs,express和jwt中为相同的路由添加多个授权