Node.js如何处理传入的请求?

问题描述

为了深入研究有关Node.js的更复杂的概念,我正在做一些研究,以确保我了解有关语言的原理以及基于该语言的基本构建块。

就我而言,Node.js依靠 reactor模式处理每个传入请求。此算法基于事件解复用器算法。第二个负责处理请求操作及其资源,然后在操作完成后将“结果”添加到事件队列。完成此过程后, Event Loop 现在负责为每个事件执行处理程序。

作为一个单线程进程,我很难理解如果事件循环并行管理所有事件队列任务,那么事件多路分解器如何处理所有传入的操作...

我已经在Node.js documentation中找到了它:

由于大多数现代内核都是多线程的,因此它们可以处理多个 在后台执行的操作。当这些操作之一 完成后,内核会告诉Node.js,以便进行适当的回调 可能会添加到轮询队列以最终执行。好 稍后在本主题中进一步详细解释。

这是否意味着事件多路分解器任务不由节点处理,并且节点仅获取结果以将其添加到事件队列中?这不是说Node不是单线程的吗?

我在网络上发现了一些有用的图形,可以清楚地说明每个请求遵循的路径,但是,很难找到一些解释该线程处理每个请求的实际时间的图形。

解决方法

在node.js中,它在单个线程中运行Javascript(假设我们不是在讨论工作线程或集群)。但是,node.js内置库中的许多异步操作(例如文件I / O或某些加密操作)都使用自己的线程来完成其任务。因此,当您调用诸如fs.open()之类的异步操作来打开文件时,它将转换为本机代码,从内部线程池中获取线程,然后该线程将打开文件。然后fs.open()函数返回您的Javascript(线程在后台继续运行)。稍后,当它完成其任务时,内部线程将事件插入到nodejs事件队列中,并且当nodejs有循环来检查事件队列时,它将找到该事件并运行与之关联的Javascript回调以将异步结果返回给您的Javascript。

因此,即使可能涉及线程,您的Java脚本也仍然是通过事件循环的单线程。

因此,nodejs的某些内部本机代码操作确实使用本机代码线程。诸如联网和计时器之类的其他事情都是在没有线程的情况下实现的。

然后,如果我发送请求从Node中的数据库获取数据,事件多路分解器将如何处理它?主线程是否会停止事件循环以处理该操作,然后在事件处理程序排队后继续执行?

诸如“事件多路复用器”之类的术语是您要应用到node.js的东西。它们根本不是node.js使用的东西,所以我不确定您要问什么。

Node.js一次运行一个事件。它没有中断驱动能力。因此,它将运行一个事件,直到该事件将控制权返回到事件循环为止(通过从启动所有操作的回调中发出return)。现在,原始事件可能尚未完成-可能正在做异步操作,这将触发另一个事件来宣布完成,但它目前已完成运行Javascript,并将控制权返回到事件循环。

当传入的Fetch请求(只是传入的http请求)到达服务器时,它首先由OS排队。然后,当事件循环有机会看到它时,它将添加到node.js事件队列中,并在完成处理之前的其他事件时以FIFO顺序进行处理。现在,nodejs事件循环不像单个事件队列那么简单。实际上,它有几个不同的队列用于不同的工作类型,并且优先处理要首先运行的队列,但是从最简单的层次上讲,您可以将其视为单个FIFO队列。而且,没有任何中断。

将事件拉出事件队列,运行与之关联的Javascript回调。当该回调返回事件循环时,获取下一个事件并执行相同的操作。

事件可以通过本机代码线程(例如可能通过文件I / O或某些加密操作完成)或通过某些内置在事件循环中的轮询机制(作为其检查的事件循环的一部分)添加到事件队列中对于某些可以运行的东西(例如联网和计时器)。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...