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

How does Node.js process incoming requests?

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

就我而言,Node.js 依靠 反应器模式 来处理每个传入请求。该算法基于 Event Demultiplexer 算法。第二个负责处理请求操作及其资源,然后,一旦操作完成,它将 'result' 添加到 Event Queue。在此过程之后,Event Loop 现在负责为每个事件执行处理程序。

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

我在 Node.js documentation:

中找到了这个

Since most modern kernels are multi-threaded, they can handle multiple operations executing in the background. When one of these operations completes, the kernel tells Node.js so that the appropriate callback may be added to the poll queue to eventually be executed. We'll explain this in further detail later in this topic.

这是否意味着 Event Demultiplexer 任务不是由 Node 处理的,Node 只是获取结果以便将其添加到 Event Queue?这是否意味着 Node 不是单线程的?

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

在 node.js 中,它 运行 是你的 Javascript 在单个线程中(假设我们不是在谈论工作线程或集群)。但是,node.js built-in 库中的许多异步操作(例如文件 I/O 或一些加密操作使用它们自己的线程来完成它们的任务。因此,当您调用诸如 fs.open() 之类的异步操作来打开文件时,它会转换为本机代码,从内部线程池中获取一个线程,然后该线程开始打开文件。 fs.open() 函数然后 returns 返回到您的 Javascript (线程在后台继续运行)。稍后当它完成它的任务时,内部线程将一个事件插入到 nodejs 事件队列中,当 nodejs 有周期检查事件队列时,它会发现该事件和 运行 相关联的 Javascript 回调它将异步结果提供回您的 Javascript.

因此,即使可能涉及线程,您的 Javascript 在事件循环中仍然是单线程的。

因此,nodejs 确实使用本机代码线程进行一些内部本机代码操作。网络和定时器等其他东西是在没有线程的情况下实现的。

Then if I send a request to fetch data from a database in Node, how does the Event Demultiplexer process It? Does the main thread stop the event loop to handle that operation and then resumes after the event handler is queued?

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

Node.js 运行一次一个事件。它没有 interrupt-driven 能力。因此,它 运行 是一个事件,直到该事件 returns 控制回到事件循环(通过从启动一切的回调发出 return )。现在,原始事件可能尚未完成 - 它可能正在执行一些异步操作,这将触发另一个事件来宣布完成,但它现在已经完成 运行ning Javascript 并将控制权返回给事件循环。

当传入的 Fetch 请求(只是传入的 http 请求)到达服务器时,它首先由 OS 排队。然后,当事件循环有机会看到它时,它被添加到 node.js 事件队列中,并在它之前的其他事件完成处理后以 FIFO 顺序提供。现在,nodejs 事件循环不像单个事件队列那么简单。它实际上有几个不同的队列用于不同类型的工作,并且优先考虑首先到达 运行 的内容,但在最简单的级别上,您可以开始将其视为单个 FIFO 队列。而且,一切都不会中断。

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

事件可以通过本机代码线程添加到事件队列中(例如可以通过文件 I/O 或一些加密操作完成)或通过事件循环中内置的一些轮询机制作为事件的一部分loop cycle 它检查某些准备就绪的东西 运行(与网络和计时器一样)。