Node.js看起来很有趣,但我必须错过一些东西- Node.js不是调好只运行在一个进程和线程上吗?

那么如何针对多核cpu和多cpu服务器进行扩展呢?毕竟,单线程服务器的速度越快越好,但对于高负载,我希望使用多个cpu。同样的道理也适用于使应用程序更快——现在的方法似乎是使用多个cpu并并行化任务。

Node.js如何适应这种情况?它的想法是以某种方式分布多个实例还是什么?


当前回答

我搜索了Clusterize一个应用程序所有可用的CPU内核,并在这里找到了我自己。我在哪里找到这个关键字是Pm2命令

pm2的例子

这是我的发现

Clusterize一个应用到所有可用的CPU内核: $ pm2 start -i Max

如果需要安装pm2,请使用这些命令

npm install -g pm2

yan add -g pm2

or

使用这里的链接

其他回答

如上所述,Cluster将在所有核上扩展和负载平衡你的应用程序。 添加如下内容

cluster.on('exit', function () {
  cluster.fork();
});

将重新启动任何失败的工作。

现在,许多人也更喜欢PM2,它为您处理集群,还提供了一些很酷的监视特性。

然后,在运行集群的几台机器前添加Nginx或HAProxy,你就有了多级故障转移和更高的负载能力。

一种方法是在服务器上运行多个node.js实例,然后在它们前面放置一个负载均衡器(最好是非阻塞的,如nginx)。

node的未来版本将允许你fork一个进程并将消息传递给它,Ryan表示他想要找到一些共享文件处理程序的方法,所以它不会是一个直接的Web Worker实现。

目前还没有一个简单的解决方案,但它仍然处于早期阶段,node是我见过的移动最快的开源项目之一,所以期待在不久的将来会有一些很棒的东西。

集群模块允许您利用机器的所有核心。事实上,您可以使用非常流行的进程管理器pm2,在不修改代码的情况下,仅用两个命令就可以利用这一点。

npm i -g pm2
pm2 start app.js -i max

[这篇文章是最新的2012-09-02(比上面更新)。]

Node.js绝对可以在多核机器上扩展。

是的,Node.js是一个线程一个进程。这是一个非常深思熟虑的设计决策,消除了处理锁定语义的需要。如果您不同意这一点,那么您可能还没有意识到调试多线程代码是多么困难。要了解Node.js进程模型的更深层次的解释,以及为什么它是这样工作的(以及为什么它永远不支持多线程),请阅读我的另一篇文章。

那么我如何利用我的16核盒子呢?

两种方式:

For big heavy compute tasks like image encoding, Node.js can fire up child processes or send messages to additional worker processes. In this design, you'd have one thread managing the flow of events and N processes doing heavy compute tasks and chewing up the other 15 CPUs. For scaling throughput on a webservice, you should run multiple Node.js servers on one box, one per core and split request traffic between them. This provides excellent CPU-affinity and will scale throughput nearly linearly with core count.


在web服务上扩展吞吐量

因为v6.0。X node .js已经包括了开箱即用的集群模块,这使得设置多个可以侦听单个端口的节点工作者变得很容易。注意,这与npm提供的旧的learnboost“cluster”模块不同。

if (cluster.isMaster) {
  // Fork workers.
  for (var i = 0; i < numCPUs; i++) {
    cluster.fork();
  }
} else {
  http.Server(function(req, res) { ... }).listen(8000);
}

工人们将竞相接受新的连接,负载最少的流程最有可能胜出。它工作得非常好,可以在多核设备上很好地扩展吞吐量。

如果你有足够的负载来关心多个核,那么你也会想做更多的事情:

运行你的Node.js服务在像Nginx或Apache这样的web代理之后——它可以做连接节流(除非你想让过载条件完全关闭),重写url,提供静态内容,并代理其他子服务。 定期回收工作进程。对于长时间运行的进程,即使是很小的内存泄漏最终也会累积起来。 设置日志收集/监控


PS:在另一篇文章的评论中有亚伦和克里斯托弗之间的讨论(写这篇文章时,它是第一篇文章)。这里有几点评论:

A shared socket model is very convenient for allowing multiple processes to listen on a single port and compete to accept new connections. Conceptually, you could think of preforked Apache doing this with the significant caveat that each process will only accept a single connection and then die. The efficiency loss for Apache is in the overhead of forking new processes and has nothing to do with the socket operations. For Node.js, having N workers compete on a single socket is an extremely reasonable solution. The alternative is to set up an on-box front-end like Nginx and have that proxy traffic to the individual workers, alternating between workers for assigning new connections. The two solutions have very similar performance characteristics. And since, as I mentioned above, you will likely want to have Nginx (or an alternative) fronting your node service anyways, the choice here is really between:

共享端口:nginx(端口80)——> Node_workers x N(共享端口3000w / Cluster)

vs

单个端口:nginx(端口80)——> {Node_worker(端口3000),Node_worker(端口3001),Node_worker(端口3002),Node_worker(端口3003)…}

单个端口的设置可以说有一些好处(进程之间的耦合可能更少,有更复杂的负载平衡决策,等等),但它肯定需要更多的工作来设置,内置的集群模块是一个低复杂性的替代方案,适用于大多数人。