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') )【问题讨论】:
你是如何推送这两个请求的?无法重现您的结果,2Home...
出现时没有为我睡觉,我正在使用 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 中的并发的主要内容,如果未能解决你的问题,请参考以下文章