【问题标题】:Why is node.js not suitable for heavy CPU apps?为什么 node.js 不适合重 CPU 应用程序?
【发布时间】:2013-06-03 04:44:09
【问题描述】:

Node.js 服务器在 I/O 和大量客户端连接方面非常高效。但是,与传统的多线程服务器相比,为什么 node.js 不适合重 CPU 应用呢?

我在这里读到了Felix Baumgarten

【问题讨论】:

  • 不管它的真假;你是从哪里得到这个声明的?你认为为什么会这样?
  • 如果您知道不是,那么您应该知道为什么不是。否则你只是在模仿别人的观点。
  • 我在这里读到了Felix Baumgarten
  • Node 是一个 Web 服务器/应用服务器。它的设计考虑了高并发用户和大量 I/O。 CPU 密集型作业不是关键思想。逐渐增加了集群以利用多核 CPU。
  • @vuvu 个人认为那篇文章不是很好,大部分东西更像是乱码

标签: javascript node.js


【解决方案1】:

如果你有异步任务,Node 是完美的,因为 java 脚本将通过工作池运行这些东西。但是,如果您运行 CPU 密集型任务(您大量使用 CPU 的地方)例如,您有十亿用户,并且您想按名称对这些人进行排序。它退出了一个 Intense 任务,这是同步的,它将阻止其他代码运行。

因此,将节点用于此类应用程序并不是一个好主意。从技术上讲,您可以找到解决此类任务的替代方案。上面的示例在 Db 中更好地解决。那么通过这个结果就很棒了。

以同样的方式避免 Intense 任务并保持 CPU 冷却以获得更好的性能

【讨论】:

    【解决方案2】:

    你可以看看这个包,the-computer,它可以帮助你以简单的方式在单个 node.js 应用程序实例中完成一些 cpu 密集型工作。

    它肯定不如原始 c++ 库那么有效,但它可以涵盖大多数通用计算案例,让您在 node.js 的花园中,同时允许您利用杯子的核心。

    【讨论】:

      【解决方案3】:

      简单的 Node.js 服务器是单线程的,这意味着任何需要很长时间才能执行的操作都会阻止程序的其余部分运行。 Node.js 应用程序通过作为一系列事件工作来设法维持高水平的并发性。当一个事件处理程序正在等待某件事发生(例如从数据库中读取)时,它会告诉 Node 继续并在此期间处理另一个事件。但是由于单个线程一次只能执行一条指令,因此这种方法无法将您从需要长时间主动执行的函数中解救出来。在多线程架构中,即使一个函数需要很长时间来计算结果,其他线程仍然可以处理其他请求——只要你有一个当时没有完全使用的核心,他们很有可能可以做到就像根本没有其他请求在运行一样快。

      为了解决这个问题,预计会占用大量 CPU 的生产 Node.js 应用程序通常会在集群中运行。这意味着您不必在一个程序的内存空间中拥有多个线程,而是在一个“主”实例的控制下运行同一程序的多个实例。每个进程都是单线程的,但由于您有多个进程,您最终会获得多线程的好处。

      【讨论】:

      • 我看了这篇文章,里面说只有事件循环是单线程的,而不是事件的计算,看看有一个线程池在dawingaaronstannard.com/post/2011/12/14/…
      • @vuvu:那篇文章有点令人困惑。他首先错误地解释了它(建议每个事件处理程序都有自己的线程),但后来正确地解释了它(您在事件处理程序中使用的许多实用程序函数在后台线程上运行,因此您不会阻塞,比如说,读取文件)。 This article 解释得更清楚了。
      • @Chuck 我知道 Promises 在给出这个答案时不存在,但是通过它的介绍,您可以将任何长时间运行的函数包装在 Promise 回调中,并使其表现得像一个异步函数,因为 NodeJS 会将您包装的函数放入 Microtask 队列中。如果该功能是 CPU 密集型且经常使用的,您不妨使用专为计算构建的语言创建专用服务器来处理这些功能/请求。现在,您可以将 NodeJS 服务器纯粹用作 API 层,与处理这些功能的服务器交互。
      【解决方案4】:

      尽管节点是异步事件模型,但它本质上是单线程的。当你启动一个 Node 进程时,你是在一个内核上运行一个具有单个线程的单个进程。所以你的 代码 不会被并行执行,只有 I/O 操作是并行的,因为它们是异步执行的。因此,长时间运行的 CPU 任务会阻塞整个服务器,通常是个坏主意。

      鉴于您只是像这样启动一个 Node 进程,但可以让多个 Node 进程并行运行。这样,您仍然可以从多线程架构中受益,尽管单个 Node 进程不能。您只需要在前面有一些负载均衡器,将请求分配到您的所有 Node 进程中。

      另一种选择是让 CPU 在单独的进程中工作,并让 Node 与这些进程交互,而不是自己完成工作。

      相关阅读:

      【讨论】:

      • 工作线程做回调呢,根据这篇文章属于线程池:aaronstannard.com/post/2011/12/14/…
      • 您的代码不会在这些工作线程上运行。它们仅在您以异步方式启动某些内容(I/O 内容)时使用,但一旦它们调用回调,您就会返回事件循环。所以你写的所有代码都在一个线程上。
      • 这个youtube视频youtu.be/8aGhZQkoFbQ详细解释了事件循环和上面的答案。
      • 这对我来说听起来不太准确。事件循环是单线程的,但如果你在 Node.js 中将它们编写为异步任务,它可以作为不同线程的任务队列管理器并并行处理你的工作。虽然一个线程可能 CPU 忙,但其他线程在当前任务完成后可以做不同的工作,而当前任务不一定是 CPU 忙工作。
      • @user2734550 不,除非您明确使用较新的工作线程,否则 CPU 密集型任务(通常是您编写的 JavaScript 代码)将在单个线程中运行。正如我在答案中所说,I/O 操作单独运行,但您的代码仅限于该单个主线程,因为 JavaScript 设计为单线程。今天仍然如此。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-21
      • 2012-06-21
      • 1970-01-01
      • 1970-01-01
      • 2021-12-01
      • 1970-01-01
      • 2019-10-05
      相关资源
      最近更新 更多