【问题标题】:Node JS Processor ArchitectureNode JS 处理器架构
【发布时间】:2019-02-08 16:03:46
【问题描述】:

我正在尝试获取有关节点 js 架构的问题的解决方案。

我知道 node js 是单线程的,适用于事件循环和非阻塞机制。

但我的问题是它背后的处理器是如何工作的,它是否同步并按优先级工作?或者它可以在单核机器上同时处理多个请求。

试图通过创建两个 API 来验证这一点 在第一个 API 中,我创建了一个 while 循环 而在第二个 API 中,我创建了一个 hello world 的响应。

然后我尝试访问 API 的第一个和第二个,但第二个 API 正在等待第一个结束,所以这里处理器直到第一个结束才处理第二个 API。

那么我能说nodejs的处理器是同步顺序工作而不是并行工作吗?

所以所有请求都必须在队列中等待之前的请求完成?

【问题讨论】:

    标签: javascript node.js architecture


    【解决方案1】:

    在我看来,问题是,这个问题的答案并不那么简单。

    1) 如果我们谈论的是 ExpressJS,那么是的,它可以同步工作

    2) 但是假设我们谈论的是 nodeJs 的内置执行,例如 http 模块,它可以异步调用(但它取决于运行 NodeJs 的操作系统)。

    NodeJs 中的不同模块从同步到异步的行为不同。 基于 NodeJS V8 的 VUlibs 实际上是基于 C++ 的库,并且这些库中的大多数都使用线程机制。像加密模块一样可以在某种程度上异步运行执行。

    【讨论】:

    • 感谢您的回复。所以你的意思是说所有用 express 编写的 API 都会一个一个地工作?并且单个 API 上的执行可以以异步方式并行执行,就像我们在 Mysql 查询执行中看到的那样。
    • @HimanshuDhingra 没错,express api 将同步运行。
    • 说 Express 同步运行过于简单化了。它基本上是一个响应异步事件的事件驱动框架。所以,我认为说它是同步的没有任何帮助。有些 Express API 是同步的,有些是异步的。例如res.send() 是非阻塞和异步的。它有一个回调告诉你什么时候完成。
    【解决方案2】:

    您的 Javascript 是单线程的 - 始终是单线程的,而且它也不是先发制人的。因此发生了一个事件,一些 Javascript 开始运行以响应该事件,并且没有其他 Javascript 可以运行,直到该事件处理程序通过从被调用以启动事件处理程序的回调中返回控制权返回给解释器。

    此时,另一个事件可以触发并运行另一个事件处理程序,并且在该事件处理程序返回系统之前,没有其他 Javascript 可以运行。

    这适用于 node.js 运行的所有 Javascript。

    啊,但并非您在 node.js 中所做的每一件事实际上都是 Javascript。假设您有两个简单的计时器:

    console.log("A");
    setTimeout(function() {
       console.log("B");
       fs.readFile("smallfile.txt", function(err, data) {
           console.log("C");
       });
       console.log("H");
    }, 1000);
    
    console.log("D");
    
    setTimeout(function() {
       console.log("E");
       fs.readFile("bigfile.txt", function(err, data) {
           console.log("F");
       });
       console.log("I");
    }, 1000);
    
    console.log("G");
    

    这将登录控制台

    A
    D
    G
    B
    H
    E
    I
    C
    F
    

    让我们讨论一下它为什么会这样做。

    A 很明显,它是第一条语句。

    然后,代码调用setTimeout(),这是非阻塞和异步的。因此,它所做的只是在未来的某个时间安排一个计时器,然后立即返回。 setTimeout() 回调在 1000 毫秒内不会准备好被调用,因此现在不会被调用。

    所以,接下来在setTimeout() 调用返回后,我们执行console.log("D");

    然后,它执行下一个setTimeout(),它现在再次安排一个 1000 毫秒的计时器并立即返回。

    然后,它执行console.log("G");

    此时,它将控制权交还给 JS 解释器,暂时无事可做。

    然后,大约 1000 毫秒后,第一个 setTimeout() 计时器在事件队列中粘贴了一个计时器事件,并且由于 JS 解释器没有运行任何其他 Javascript,它会抓取该事件并运行与该事件关联的 JS 回调。这会立即记录console.log("B");

    然后,它调用fs.readFile("smallfile.txt", ...)。这又是非阻塞和异步的,所以它所做的只是告诉底层本机代码 fs 模块实现从该文件中读取所有数据,然后立即返回。然后它运行console.log("H");。至此,这个事件处理程序就完成了,并将控制权返回给解释器。

    同时,第二个setTimeout() 事件已准备就绪,因此 JS 解释器从事件队列中提取该事件​​并调用与其关联的回调。

    运行console.log("E");,然后调用 fs.readFile("bigfile.txt", ...). This is again non-blocking and asynchronous so all it does is tell the underlying native code fs module implementation to go read all the data from this file and then returns immediately. It then runsconsole.log("I");`。至此,这个事件处理程序就完成了,并将控制权返回给解释器。

    一段时间后,fs.readFile("smallfile.txt", ...) 完成并将一个事件插入到事件队列中。由于 JS 解释器无事可做,它会获取该事件并运行与之关联的回调,我们会看到 console.log("C") 的结果。然后完成并将控制权返回给解释器。

    一段时间后,fs.readFile("bigfile.txt", ...) 完成并将一个事件插入到事件队列中。由于 JS 解释器无事可做,它会获取该事件并运行与之关联的回调,我们会看到 console.log("F") 的结果。然后完成并将控制权返回给解释器。

    此时一切都完成了。

    希望您能看到异步操作(在本机代码中实现可以与使用其他 CPU 内核的 Javascript 执行并行运行)并通过将事件放入事件队列中与 Javascript 执行同步。当 JS 解释器运行完事件处理程序后,它可以在事件队列中查找下一个要运行的事件,或者如果现在没有,则进入睡眠状态,直到下一个事件插入事件队列。

    因此,虽然本机代码实现可以与 Javascript 并行运行,但仍然只有一个 Javascript 执行线程一次运行,并且另一个线程无法运行,直到前一个线程通过从任何返回将控制权返回给解释器事件处理程序回调开始执行。

    在事件循环内部,实际上有一堆不同类型的队列用于不同类型的事件,它们相对于彼此有一些不同的优先级,所以它比我描述的要复杂一些在这里,但核心概念是一个事件驱动系统,它一次只运行与一个事件相关联的 Javascript(单线程)和一些操作的本地代码实现,这些操作可以与 Javascript 执行并行运行,这些操作与 Javascript 的单线程同步通过事件队列执行。

    【讨论】:

    • 感谢您的回答。它真的帮了我很多。但是正如您所说的“代码可以使用其他 CPU 内核与 Javascript 执行并行运行”,所以如果我们使用多个 CPU 内核,那么为什么我们需要 PM2 来使用多个 CPU 内核。是为了创建多个队列吗?
    • @HimanshuDhingra - 只有不是用 Javascript 编写的本机代码才能并行运行。正如您所希望看到的,我已经多次说过,无论您拥有多少个内核,Javascript 都只有一个线程。 PM2有几十个功能。其中之一是集群,它运行你的 node.js 应用程序的多个副本,以便你可以应用多个内核来运行 Javascript。
    猜你喜欢
    • 1970-01-01
    • 2011-02-07
    • 2020-09-05
    • 2019-09-04
    • 1970-01-01
    • 1970-01-01
    • 2013-05-06
    • 1970-01-01
    • 2021-08-12
    相关资源
    最近更新 更多