73

老实说,我还没有完全理解它——我什至理解 Node.js 是如何工作的,作为使用事件模型的单线程。我只是不明白这比 Apache 好,以及如果它是单线程的,它是如何水平扩展的。

4

2 回答 2

94

我发现 Tomislav Capan 的这篇博文很好地解释了这一点:
我为什么要使用 Node.js?逐案介绍

与 Apache 相比,我对 Node 0.10 要点的解释:

好的部分

  • Node.js 避免为每个请求启动线程,或者不需要像 Apache 那样处理对一组线程的请求池。因此,它处理请求的开销较小,并且擅长快速响应。
  • Node.js 可以将请求的执行委托给单独的组件,并专注于新的请求,直到委托的组件返回处理结果。这是异步代码,由事件模型实现。Apache 在池中串行执行请求,并且当其模块之一只是在等待任务完成时无法重用线程。然后,Apache 将对请求进行排队,直到池中的线程再次可用。
  • Node.js 使用 JavaScript,因此在传递和操作从外部 Web API 源(如 MongoDB)检索到的 JSON 方面非常快,从而减少了每个请求所需的时间。Apache 模块(如 PHP)可能需要更多时间,因为它们无法有效地解析和操作 JSON,因为它们需要编组来处理数据。

坏的部分

注意:下面列出的大部分不良部分将在即将发布的 0.12 版本中得到改进,请注意。

  • Node.js不擅长计算密集型任务,因为每当它执行长时间运行的操作时,由于它的单线程,它会将所有其他传入请求排队。Apache 通常会有更多可用线程,并且操作系统会在这些线程之间巧妙而公平地安排 CPU 时间,仍然允许处理新线程,尽管速度会慢一些。除非 Apache 中的所有可用线程都在处理请求,否则 Apache 也会开始对请求进行排队。
  • Node.js 没有充分利用多核 CPU,除非您创建 Node.js 集群或启动子进程。具有讽刺意味的是,如果您执行后两者,您可能会增加更多的编排开销,这与 Apache 的问题相同。从逻辑上讲,您还可以启动更多 Node.js 进程,但这不是由 Node.js 管理的。你必须测试你的代码,看看什么效果更好;1) Node.js 内的多线程,带有集群和子进程,或 2) 多个 Node.js 进程。

缓解措施

所有服务器平台都有上限。Node.js 和 Apache 都将在某个时候达到它。

  • 当您有繁重的计算任务时,Node.js 会以最快的速度达到它。
  • 当你向它抛出大量需要长时间串行执行的小请求时,Apache 会以最快的速度到达它。

你可以做三件事来扩展 Node.js 的吞吐量

  1. 通过设置集群、使用子进程或使用多进程编排器(如Phusion Passenger )来利用多核 CPU
  2. 设置与消息队列连接的工作角色。这将是针对计算密集型长时间运行请求的最有效解决方案;将它们卸载到工人农场。这会将您的服务器分成两部分;1) 接受用户请求的面向公众的文书服务器,以及 2) 处理长时间运行任务的私有工作服务器。两者都与消息队列相连。文书服​​务器将消息(传入的长时间运行的请求)添加到队列中。工作角色侦听传入的消息,处理这些消息,并可能将结果返回到消息队列中。如果需要请求/响应,那么文书服务器可以异步等待响应消息到达消息队列。消息队列的示例是RabbitMQZeroMQ
  3. 设置负载平衡器并启动更多服务器。现在您可以有效地使用硬件并委派长时间运行的任务,您可以水平扩展。如果您有负载平衡器,则可以添加更多文书服务器。使用消息队列,您可以添加更多工作服务器。您甚至可以在云中进行设置,以便按需扩展。
于 2014-02-15T04:06:47.073 回答
38

这取决于你如何使用它。Node.js 默认是单线程的,但使用(相对)新的集群模块,您可以跨多个线程水平扩展。

此外,您的数据库需求还将决定节点扩展的有效性。例如,将 MySQL 与 node.js 一起使用不会像使用 MongoDB 那样为您带来几乎一样的好处,因为 MongoDB 和 node.js 都是事件驱动的性质。

以下链接有很多不同设置的系统基准测试: http ://www.techempower.com/benchmarks/

Node.js 的排名不是最高的,但与使用 nginx 的其他设置相比(他们的表上没有 apache,但足够接近),它的表现相当不错。

不过,这在很大程度上取决于您的需求。我相信如果您只是为静态网站提供服务,建议您坚持使用更传统的堆栈。然而,人们使用 node.js 为其他需求做了一些令人惊奇的事情:http: //blog.caustik.com/2012/08/19/node-js-w1m-concurrent-connections/(c10k?哈!)

编辑:值得一提的是,你真的不只是用 node.js '替换' apache。您将替换 apache AND php(在典型的灯堆栈中)。

于 2013-05-16T04:39:57.833 回答