node.js - Node 事件循环困惑

标签 node.js asynchronous nonblocking

我有点困惑,不知道我是否完全理解nodeJS事件循环/非阻塞I/O概念。

假设在我的服务器中我有:

app.get('/someURL', AuthHandler.restrict, MainHandler.findAllStocksFromUser);

findAllStocksFromUser() 的定义如下:

findAllStocksFromUser(req,res) {
     /* Do some terribly inefficient, heavy computation*/
     res.send(/*return something*/);
}

现在假设有 5 个请求进来。据我了解,对于每个进来的请求,都会将回调(在本例中为 findAllStocksFromUser())添加到事件循环队列中,并且每次更新都会调用回调。

问题:

  1. “极其低效、繁重的计算”不会影响服务器有效接收请求并立即将回调添加到队列的能力,对吗?

  2. 但是“极其低效、繁重的计算”会阻塞其他回调,直到它完成为止,并导致服务器效率低下,对吗?

最佳答案

在node.js中,你的Javascript是单线程的。这意味着一次只运行一段 Javascript。因此,一旦请求处理程序开始运行,它就会一直运行,直到完全完成并返回到调用它的系统,或者直到它启动异步操作(数据库、文件、网络等),然后返回到调用它的系统。只有这样,其他请求才能开始处理。

因此,如果您的“繁重计算”确实是大量同步 Javascript 运行,那么在运行时不会处理其他请求。如果该“繁重计算”实际上包含大量异步操作,那么在处理程序等待异步操作响应时,其他请求将开始运行。

现在,回答您的具体问题:

So now let's say 5 requests come in. As I understand, with each request that comes in, a callback, in this case findAllStocksFromUser(), is added to the eventloop queue, and with every tick, the callbacks are called.

这不太正确。传入的请求已排队,但排队的级别远低于仅排队回调的级别。它在服务器的 Javascript 部分看到请求之前就已排队(在某处的 native 代码中)。

The "terribly inefficient, heavy computation" won't effect the server's ability to efficiently receive requests as they come in and immediately add their callbacks to the queue, correct?

传入的请求将由底层 TCP 基础设施或实现服务器的 Node.js 中的 native 代码(不在单线程 JS 中运行)排队。因此,长时间运行的 Javascript 不会阻止传入请求排队(除非某些内部队列已满)。

But the "terribly inefficient, heavy computation" is going to block the other callbacks until it's done and cause the server to be inefficient in that way, right?

正确。如果这种低效、繁重的计算是同步代码,那么它将一直运行直到完成,并且在运行时没有其他请求运行。

对于 Node.js 中的繁重计算代码,通常的解决方案是重新设计它以运行得更快,或者在可能的情况下使用异步操作,或者将其移出主进程并启动子进程或子工作集群来处理繁重的计算。然后,这允许您的主请求处理程序将这种繁重的计算视为异步操作,并允许在主 Node.js 线程之外完成繁重的工作时运行其他事情。

虽然有时这需要更多的编码工作,但也可以将长时间运行的计算分成多个 block ,以便可以执行一个工作 block ,然后使用 setImmediate() 安排下一个 block 工作,允许在您的工作 block 之间处理其他排队的项目。由于现在建立一个工作人员池并把工作交给他们是相当快的,我可能会喜欢这种方法,因为它还可以让您更好地利用多个 CPU,并且省去了“分块”的复杂性工作和编写代码以有效地处理这种方式。

关于node.js - Node 事件循环困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32468482/

相关文章:

javascript - JavaScript 中的执行队列是如何生成的?

asynchronous - 如何记录异步瘦+sinatra+ Rack 请求?

java - 非阻塞 IO 和 HystrixObservableCommand

每个连接模型的 Java 线程与 NIO

javascript - 在 Crontab 中运行 Node JS 命令和 Linux 命令

node.js - object object error in signup with passport in express 对象错误

javascript - 正则表达式 - 将 html 元素与多行上的子元素匹配

node.js - 如何使用 Node 模块 kappa?

javascript - 如何使用 jQuery 异步上传文件?

java - 非阻塞 http 服务器,java nio,python tornado eventlet