是什么让 Node.js 比 Apache 更具可扩展性?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16578874/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What specifically makes Node.js more scalable than Apache?
提问by MaiaVictor
To be honest I've not understood it completely yet - and I even do understand how Node.js works, as a single thread using the event model. I just don't get how this is better than Apache, and how it scales horizontally if it's single-threaded.
老实说,我还没有完全理解它——我什至理解 Node.js 是如何工作的,作为使用事件模型的单线程。我只是不明白这比 Apache 有什么好处,以及如果它是单线程的,它是如何水平扩展的。
回答by Bart Verkoeijen
I've found that this blog post by Tomislav Capan explains it very well:
Why The Hell Would I Use Node.js? A Case-by-Case Introduction
我发现 Tomislav Capan 的这篇博文很好地解释了它:
我为什么要使用 Node.js?逐案介绍
My interpretation of the gist of it, for Node 0.10, compared to Apache:
与 Apache 相比,我对 Node 0.10 的要点的解释:
The good parts
好的部分
- Node.js avoids spinning up threadsfor each request, or does not need to handle pooling of requests to a set of threads like Apache does. Therefore it has less overhead to handle requests, and excels at responding quickly.
- Node.js can delegate execution of the requestto a separate component, and focus on new requests until the delegated component returns with the processed result. This is asynchronous code, and is made possible by the eventing model. Apache executes requests in serial within a pool, and cannot reuse the thread when one of its modules is simply waiting for a task to complete. Apache will then queue requests until a thread in the pool becomes available again.
- Node.js talks JavaScriptand is therefore very fast in passing through and manipulating JSON retrieved from external web API sources like MongoDB, reducing time needed per request. Apache modules, like PHP, may need more time, because they cannot efficiently parse and manipulate JSON because they need marshallingto process the data.
- Node.js 避免为每个请求启动线程,或者不需要像 Apache 那样处理对一组线程的请求池。因此它处理请求的开销较小,并且擅长快速响应。
- Node.js 可以将请求的执行委托给一个单独的组件,并专注于新的请求,直到委托的组件返回处理后的结果。这是异步代码,由事件模型实现。Apache 在池中串行执行请求,并且当其模块之一只是等待任务完成时不能重用线程。然后 Apache 将请求排队,直到池中的线程再次可用。
- Node.js 使用 JavaScript,因此在传递和操作从外部 Web API 源(如 MongoDB)检索的 JSON 方面非常快,从而减少了每个请求所需的时间。Apache 模块(如 PHP)可能需要更多时间,因为它们无法有效解析和操作 JSON,因为它们需要编组来处理数据。
The bad parts
坏的部分
Note:most of the bad parts listed below will be improved with the upcoming version 0.12, something to keep aware of.
注意:下面列出的大多数不好的部分将在即将发布的 0.12 版本中得到改进,需要注意一些事项。
- Node.js sucks at computational intensive tasks, because whenever it does something long running, it will queue all other incoming requests, due to its single thread. Apache will generally have more threads available, and the OS will neatly and fairly schedule CPU time between these threads, still allowing new threads to be handled, albeit a bit slower. Except when all available threads in Apache are handling requests, then Apache will also start queueing requests.
- Node.js doesn't fully utilize multi-core CPUs, unless you make a Node.js cluster or spin up child processes. Ironically, if you do the latter two, you may add more orchestrating overhead, the same issue that Apache has. Logically you could also spin up more Node.js processes, but this is not managed by Node.js. You would have to test your code to see what works better; 1) multi-threading from within Node.js with clusters and child processes, or 2) multiple Node.js processes.
- Node.js 不擅长计算密集型任务,因为每当它执行长时间运行的任务时,由于它的单线程,它会将所有其他传入请求排队。Apache 通常会有更多的可用线程,并且操作系统会在这些线程之间巧妙而公平地安排 CPU 时间,仍然允许处理新线程,尽管速度会慢一些。除非 Apache 中所有可用线程都在处理请求,否则 Apache 也会开始对请求进行排队。
- Node.js 不会充分利用多核 CPU,除非您创建 Node.js 集群或启动子进程。具有讽刺意味的是,如果您执行后两者,则可能会增加更多的编排开销,这与 Apache 存在的问题相同。从逻辑上讲,您还可以启动更多 Node.js 进程,但这不是由 Node.js 管理的。你必须测试你的代码,看看哪个效果更好;1) 在 Node.js 中使用集群和子进程进行多线程处理,或者 2) 多个 Node.js 进程。
Mitigations
缓解措施
All server platforms have an upper limit. Node.js and Apache both will reach it at some point.
所有服务器平台都有上限。Node.js 和 Apache 都会在某个时候达到它。
- Node.js will reach it the fastest when you have heavy computational tasks.
- Apache will reach it the fastest when you throw tons of small requests at it that require long serial execution.
- 当你有繁重的计算任务时,Node.js 会以最快的速度达到它。
- 当你向它抛出大量需要长时间串行执行的小请求时,Apache 会以最快的速度到达它。
Three things you could do to scale the throughput of Node.js
你可以做三件事来扩展 Node.js 的吞吐量
- Utilize multi-core CPUs, by either setting up a cluster, use child processes, or use a multi-process orchestrator like Phusion Passenger.
- Setup worker roles connected with a message queue. This will be the most effective solution against computational intensive long running requests; off-load them to a worker farm. This will split up your servers in two parts; 1) public facing clerical servers that accept requests from users, and 2) private worker servers handling long running tasks. Both are connected with a message queue. The clerical servers add messages (incoming long-running requests) to the queue. The worker roles listen for incoming messages, handle those, and may return the result into the message queue. If request/response is needed, then the clerical server could asynchronously wait for the response message to arrive in the message queue. Examples of message queues are RabbitMQand ZeroMQ.
- Setup a load balancer and spin up more servers.Now that you efficiently use hardware and delegate long running tasks, you can scale horizontally. If you have a load balancer, you can add more clerical servers. Using a message queue, you can add more worker servers. You could even set this up in the cloud so that you could scale on demand.
- 通过设置集群、使用子进程或使用多进程编排器(如Phusion Passenger)来利用多核 CPU。
- 设置与消息队列连接的工作角色。这将是针对计算密集型长时间运行请求的最有效解决方案;将它们卸载到工人农场。这会将您的服务器分成两部分;1) 接受用户请求的面向公众的文书服务器,以及 2) 处理长时间运行任务的私人工作服务器。两者都与消息队列相连。文书服务器将消息(传入的长时间运行的请求)添加到队列中。工作角色监听传入的消息,处理这些消息,并可能将结果返回到消息队列中。如果需要请求/响应,那么文书服务器可以异步等待响应消息到达消息队列。消息队列的例子是RabbitMQ和ZeroMQ。
- 设置负载平衡器并启动更多服务器。现在您可以有效地使用硬件并委派长时间运行的任务,您可以水平扩展。如果您有负载平衡器,则可以添加更多文书服务器。使用消息队列,您可以添加更多工作服务器。您甚至可以在云中进行设置,以便您可以按需扩展。
回答by Kevin Lee
It depends on how you use it. Node.js is single threaded by default, but using the (relatively) new cluster module you can scale horizontally across multiple threads.
这取决于你如何使用它。默认情况下,Node.js 是单线程的,但使用(相对)新的集群模块,您可以跨多个线程水平扩展。
Furthermore, your database needs will also dictate how effective scaling is with node. For example, using MySQL with node.js won't get you nearly as much benefit as using MongoDB, because of the event driven nature of both MongoDB and node.js.
此外,您的数据库需求还将决定使用 node.js 扩展的有效性。例如,由于 MongoDB 和 node.js 的事件驱动特性,将 MySQL 与 node.js 结合使用不会给您带来与使用 MongoDB 一样多的好处。
The following link has a lot of nice benchmarks of systems with different setups: http://www.techempower.com/benchmarks/
以下链接有很多不同设置的系统的很好的基准测试:http: //www.techempower.com/benchmarks/
Node.js doesn't rank the highest but compared to other setups using nginx (no apache on their tables, but close enough) it does pretty well.
Node.js 的排名不是最高,但与其他使用 nginx 的设置(他们的表上没有 apache,但足够接近)相比,它做得很好。
Again though, it highly depends on your needs. I believe if you are simply serving static websites it is recommend you stick with a more traditional stack. However people have done some amazing things with node.js for other needs: http://blog.caustik.com/2012/08/19/node-js-w1m-concurrent-connections/(c10k? ha!)
不过,这在很大程度上取决于您的需求。我相信如果您只是为静态网站提供服务,建议您坚持使用更传统的堆栈。然而,人们已经用 node.js 做了一些令人惊奇的事情来满足其他需求:http: //blog.caustik.com/2012/08/19/node-js-w1m-concurrent-connections/(c10k?哈哈!)
Edit: It is worth mentioning that you really aren't 'replacing' just apache with node.js. You would be replacing apache AND php (in a typical lamp stack).
编辑:值得一提的是,你真的不是用 node.js 来“替换”apache。您将替换 apache 和 php(在典型的灯组中)。

