【问题标题】:Concurrent in NodejsNodejs 中的并发
【发布时间】: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

标签: node.js concurrency


【解决方案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 事件循环。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-06
      • 2020-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-10
      • 2015-06-03
      相关资源
      最近更新 更多