Nodejs 中的并发

Posted

技术标签:

【中文标题】Nodejs 中的并发【英文标题】:Concurrent in Nodejs 【发布时间】:2019-01-08 03:50:06 【问题描述】:

我有如下节点服务器。我推了 2 个请求 几乎同时(使用相同的 url = "localhost:8080/")。 我的问题是:“为什么服务器等待第一个请求处理完成,然后处理第二个请求”?

我的测试控制台输出: 家.. 家..

(注:第 2 行将在 12 秒后显示) - server.js:

var express = require('express') var app = express() app.use(express.json()) app.get('/', async(request, response) => 尝试 console.log('首页 ...') 等待睡眠(12000) response.send('结束') 捕捉(错误) response.end('错误') ) 功能睡眠(毫秒) return new Promise(resolve => setTimeout(resolve, ms)); var server = app.listen(8080, '127.0.0.1', async () => var host = server.address().address var port = server.address().port console.log('===================== START SERVER ===================') console.log('* 在 http://%s:%s 上运行(按 CTRL+C 退出)', host, port) console.log('* 创建时间' + new Date() + '\n') )

【问题讨论】:

你是如何推送这两个请求的?无法重现您的结果,2 Home... 出现时没有为我睡觉,我正在使用 2 bash 实例与 curl 【参考方案1】:

"为什么服务器等待第一个请求处理完成,然后是第二个请求 将被处理”?

这不适用于 Node.Js。您正在代码中进行同步和异步调用。对sleep() 方法的异步调用等待12 秒运行。

现在这并不意味着异步调用要等到同步调用完成。这是同步行为。请注意以下示例

asyncFunction1()
asyncFunction2()
asyncFunction3() 

在这里,每当第一个函数开始运行时,node.js 释放线程/块,然后第二个函数开始运行,再次节点释放线程,因此对第三个函数的调用开始。每个函数在完成时都会返回响应,并且不会等待其他函数的返回。

NodeJs 是单线程的或具有非阻塞 i/o 架构。异步特性是它的美。

【讨论】:

只是为了补充@unclexo 的上述答案,nodejs 引擎本身是单线程的,因此如果您同时触发 2 个请求,那么节点会一一处理它们。现在,由于您在 sleep 调用之前编写了“等待”,节点引擎将在此时停止,所有新请求自然必须等待。【参考方案2】:

同意@unclexo - 了解阻塞/非阻塞调用是什么,并围绕它优化你的代码。如果你真的想为并行请求增加容量,你可以考虑利用集群模块。

https://nodejs.org/api/cluster.html

这将启动子进程并将 HTTP 请求代理给这些子进程。每个子进程都可以按自己的意愿阻塞,并且不会影响其他进程(除非它们之间存在竞争条件)。

【讨论】:

【参考方案3】:

您通过在app.get('/'... 调用await 来阻止另一个请求。 如果您希望 sleep 方法在请求之间异步运行,请将其包装在新的 async 函数中。代码会是这样的:

app.get('/', (request, response) => 
    try 
        print()
        response.send('End')
     catch (error) 
        response.end('Error')
    
)

async function print() 
    await sleep(12000)
    console.log('Home ...')


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

这样,如果你发送一个请求,然后再发送另一个请求,第二个请求的 print() 函数将在第一个请求之后执行,而无需等待 12 秒。因此,在请求发送后大约 12 秒会打印 2 个Home ...。要对此有更多了解,您应该了解 NodeJS 事件循环。

【讨论】:

以上是关于Nodejs 中的并发的主要内容,如果未能解决你的问题,请参考以下文章

nodejs每秒并发多高

用nodejs实现并发请求,每结束一个则发起新的请求

node高并发

nodejs爬虫使用async控制并发写一个小说爬虫

nodejs + mongodb 并发控制

nodejs 单线程 高并发