是什么让Node.js比Apache更具可扩展性?



老实说,我还没有完全理解它-我甚至知道Node.js是如何工作的,作为一个使用事件模型的单线程。我只是不明白为什么它比Apache更好,如果它是单线程的,它是如何横向扩展的。

我发现Tomislav Capan的这篇博文解释得很好:
为什么我要用Node.js?逐个介绍

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

好的部分

  • 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抛出大量需要长时间串行执行的小请求时,Apache将最快地达到它。

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

  1. 利用多核cpu ,通过设置集群,使用子进程,或使用多进程编排器,如Phusion Passenger
  2. 设置与消息队列连接的worker角色。这将是针对计算密集型长时间运行请求的最有效解决方案;把它们卸到工人农场。这将把服务器分成两部分;1)接受用户请求的面向公众的文书服务器,以及2)处理长时间运行任务的私人工作服务器。两者都通过消息队列连接。文书服务器将消息(传入的长时间运行的请求)添加到队列中。工作者角色监听传入的消息,处理这些消息,并可能将结果返回到消息队列中。如果需要请求/响应,那么文书服务器可以异步等待响应消息到达消息队列。消息队列的例子有RabbitMQ和ZeroMQ。
  3. 设置负载平衡器并启动更多服务器。现在您可以有效地使用硬件并委托长时间运行的任务,您可以横向扩展。如果您有一个负载平衡器,您可以添加更多的文书服务器。使用消息队列,您可以添加更多的辅助服务器。你甚至可以在云中设置它,这样你就可以按需扩展。

这取决于你如何使用它。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和php(在一个典型的灯栈中)。

最新更新