多核机器上的 Node.js

2024-01-13

Node.js http://en.wikipedia.org/wiki/Node.js看起来很有趣,BUT我一定错过了一些事情 - Node.js 不是只调整为在单个进程和线程上运行吗?

那么它如何针对多核 CPU 和多 CPU 服务器进行扩展呢?毕竟,让单线程服务器尽可能快固然很棒,但对于高负载,我想使用多个 CPU。同样的道理也适用于让应用程序更快——今天看来,方法是使用多个 CPU 并并行化任务。

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


[这篇文章截至 2012 年 9 月 2 日是最新的(比上面更新)。]

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

是的,Node.js 是每进程一个线程。这是一个经过深思熟虑的设计决策,消除了处理锁定语义的需要。如果您不同意这一点,那么您可能还没有意识到调试多线程代码有多么困难。要更深入地解释 Node.js 进程模型以及为什么它以这种方式工作(以及为什么它永远不会支持多线程),请阅读我的另一篇文章 https://stackoverflow.com/questions/1884724/what-is-node-js/6782438#6782438.

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

两种方式:

  • 对于图像编码等大型计算任务,Node.js 可以启动子进程或向其他工作进程发送消息。在此设计中,您将有一个线程管理事件流,N 个进程执行繁重的计算任务并占用其他 15 个 CPU。
  • 为了扩展 Web 服务的吞吐量,您应该在一个机器上运行多个 Node.js 服务器,每个核心一个,并在它们之间分配请求流量。这提供了出色的 CPU 亲和力,并且吞吐量随核心数量几乎呈线性扩展。

扩展 Web 服务的吞吐量

自 v6.0.X 起 Node.js 已包含集群模块 http://nodejs.org/docs/latest/api/cluster.html开箱即用,这使得可以轻松设置可以在单个端口上侦听的多个节点工作程序。请注意,这与通过以下方式获得的旧 learnboost“集群”模块不同npm http://en.wikipedia.org/wiki/Npm_%28software%29.

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

工作进程将竞争接受新连接,负载最少的进程最有可能获胜。它工作得很好,并且可以在多核机器上很好地提高吞吐量。

如果您有足够的负载来关心多个核心,那么您还需要做更多的事情:

  1. 在网络代理后面运行 Node.js 服务,例如Nginx http://en.wikipedia.org/wiki/Nginx or Apache http://en.wikipedia.org/wiki/Apache_HTTP_Server- 可以进行连接限制(除非您希望过载条件使设备完全关闭)、重写 URL、提供静态内容以及代理其他子服务。

  2. 定期回收您的工作进程。对于长时间运行的进程,即使是很小的内存泄漏最终也会累积起来。

  3. 设置日志收集/监控


PS:在另一篇文章的评论中,亚伦和克里斯托弗之间进行了讨论(在撰写本文时,这是顶帖)。对此有几点评论:

  • 共享套接字模型非常方便,允许多个进程侦听单个端口并竞争接受新连接。从概念上讲,您可以认为预分叉的 Apache 这样做时有一个重要的警告:每个进程只接受一个连接,然后就会终止。 Apache 的效率损失在于派生新进程的开销,与套接字操作无关。
  • 对于 Node.js 来说,让 N 个工作线程在单个套接字上竞争是一个极其合理的解决方案。另一种方法是设置一个像 Nginx 这样的机载前端,并将代理流量分配给各个工作人员,在工作人员之间交替分配新连接。这两种解决方案具有非常相似的性能特征。而且,正如我上面提到的,无论如何,您可能都希望让 Nginx(或替代方案)前置您的节点服务,因此这里的选择实际上是:

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

vs

个别端口:nginx (port 80) --> {Node_worker (port 3000), Node_worker (port 3001), Node_worker (port 3002), Node_worker (port 3003) ...}

可以说,单独的端口设置有一些好处(可能会减少进程之间的耦合,具有更复杂的负载平衡决策等),但设置肯定需要更多工作,并且内置集群模块的成本较低。 -适合大多数人的复杂性替代方案。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

多核机器上的 Node.js 的相关文章

随机推荐