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


73

老实说,我还没有完全理解它-我什至确实了解Node.js是如何使用事件模型作为单个线程运行的。我只是不知道它比Apache更好,以及如果它是单线程,它如何水平扩展。

Answers:


93

我发现Tomislav Capan撰写的此博客文章对此做了很好的解释:
为什么我会使用Node.js?个案介绍

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

好的零件

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

不良零件

注意:下面列出的大多数不良部分将在即将发布的0.12版本中得到改善,这一点需要注意。

  • Node.js占用大量计算密集型任务,因为每当它执行长时间运行的操作时,由于其线程单一,它将对所有其他传入请求进行排队。Apache通常将有更多可用线程,并且OS将整齐合理地调度这些线程之间的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. 设置负载平衡器并启动更多服务器。现在,您可以有效地使用硬件并委派长时间运行的任务,现在可以水平扩展了。如果您有负载平衡器,则可以添加更多的文书服务器。使用消息队列,可以添加更多工作服务器。您甚至可以在云中进行设置,以便可以按需扩展。

这是一个很好的答案。特别是关于MQ的技巧。想知道他们有什么用。谢谢!
oligofren 2015年

4
任何计算量大的任务都应异步完成。如果不严重依赖长时间运行的任务的异步执行,则节点实际上将不可用。这是节点可伸缩性的主要特征(就单个实例而言),并且在此要牢记非常重要。
亚当·托利

大点@AdamTolley。进一步说,我对计算密集型任务的意思是,它不容易分解为多个异步部分。必须在CPU上同步完成一些操作。例如,渲染图像。如果您无法将异步代码委托或卸载到另一个CPU或进程,那么异步代码将无济于事。但是,如果您可以分解任务,那么可以像操作系统一样将其他异步任务切入时间片中。
Bart Verkoeijen

纯TCP协议比所有协议最好,但是不能在公共站点主机上使用。一些商人每月在Cloud Server中支付3,000美元,而不是使用可以满足要求的通用托管。
PadronizaçãoSA

38

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

此外,您的数据库需求也将决定节点的有效扩展。例如,由于MongoDB和node.js都是事件驱动的,因此将MySQL与node.js结合使用不会带来与使用MongoDB一样多的收益。

以下链接为使用不同设置的系统提供了许多不错的基准测试:http : //www.techempower.com/benchmarks/

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

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

编辑:值得一提的是,您实际上并没有用node.js来“替换” Apache。您将要替换apache和php(在典型的灯堆中)。


1
很棒的答案,这实际上增加了我的问题。首先,我不太了解那个家伙所做的特别工作-他为每个可用核心派生了一个工人,是吗?他在那儿正在做什么网格伏都教?如果他正在做的只是为Hello World服务,为什么他需要通过节点进行消息传递?另外,我在那里几乎不了解任何这些框架。例如,去吧,我认为那只是一种编程语言。我可以在任何地方概述正在发生的事情,实际上是什么和做什么?那真是太好了。谢谢!
MaiaVictor

2
他实际上只为服务器使用1个工作进程。他正在做的是使用Amazon EC2动态生成500个客户端实例,以创建连接(每个连接2000个,总计100万个),并维护与单个流程Web服务器的连接,同时在所有这些客户端之间来回发送消息。我应该从他的第一篇文章开始链接,他的联系开始于100k,然后逐步上升(blog.caustik.com/2012/04/08/…)。就Go等而言,我建议只是谷歌搜索它们。
凯文·李

Apache是那么好,多数民众赞成支持国际HTTP轮询,哈哈
PadronizaçãoSA
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.