Node.js看起来很有趣,但是我肯定错过了一些东西——Node.js不是被调整为只在单个进程和线程上运行吗
那么对于多核CPU和多CPU服务器,它是如何扩展的呢?毕竟,使单线程服务器尽可能快是很好的,但对于高负载,我希望使用几个CPU。使应用程序更快也是如此——似乎今天的方法是使用多个CPU并并行化任务
Node.js如何适应这张图片?它的想法是以某种方式分发多个实例还是什么
[这篇文章是截至2012-09-02的最新文章(比上面更新)。]
Node.js绝对可以在多核机器上扩展
是的,Node.js是每个进程一个线程。这是一个经过深思熟虑的设计决策,不需要处理锁定语义。如果您不同意这一点,您可能还没有意识到调试多线程代码有多么困难。有关Node.js进程模型的更深入解释,以及为什么它会以这种方式工作(以及为什么它永远不支持多线程),请阅读我的另一篇文章
那么我如何利用我的16芯机箱呢
两种方式:
- 对于大型繁重的计算任务(如图像编码),Node.js可以启动子进程或向其他工作进程发送消息。在这个设计中,一个线程管理事件流,N个进程执行繁重的计算任务,占用其他15个CPU
- 为了扩展Web服务的吞吐量,您应该在一个机器上运行多个Node.js服务器,每个核心一个,并在它们之间分割请求流量。这提供了极好的CPU亲和力,并将吞吐量几乎与内核数成线性关系
在Web服务上扩展吞吐量
因为v6.0.X Node.js包含了集群模块,这使得设置多个可以在单个端口上侦听的节点工作程序变得很容易。请注意,这与npm提供的旧的learnboost“cluster”模块不同
if(cluster.isMaster){
//叉工。
对于(变量i=0;i<;numpus;i++){
cluster.fork();
}
}否则{
服务器(函数(req,res){…}).listen(8000);
}
员工将竞争接受新的连接,负载最少的流程最有可能获胜。它工作得很好,可以在多核机箱上很好地扩展吞吐量
如果您有足够的负载来关心多个核心,那么您还需要做一些事情:
-
在像Nginx或Apache这样的web代理后面运行Node.js服务——这可以进行连接限制(除非您希望过载条件完全关闭该框)、重写URL、提供静态内容以及代理其他子服务
-
定期回收工作进程。对于长时间运行的进程,即使是很小的内存泄漏最终也会累积起来
-
设置日志收集/监视
附:亚伦和克里斯托弗在另一篇文章的评论中进行了讨论(在撰写本文时,这是第一篇文章)。对此有几点评论:
- 共享套接字模型非常方便,允许多个进程在单个端口上侦听并竞争接受新连接。从概念上讲,您可以认为预处理的Apache在这样做的时候会有一个重要的警告,即每个进程只接受一个连接,然后就死掉了。Apache的效率损失在于分叉新进程的开销,而与套接字操作无关
- 对于Node.js,让N个工人在一个套接字上竞争是一个非常合理的解决方案。另一种方法是设置一个类似Nginx的机箱前端,并将代理通信量分配给各个工作者,在工作者之间交替分配新的连接。这两种解决方案具有非常相似的性能特征。而且,正如我上面提到的,您可能希望Nginx(或其他替代方案)以任何方式支持您的节点服务,因此这里的选择实际上是:
共享端口:nginx(端口80)-->Node\u workers x N(共享端口3000 w/集群)
vs
单个端口:nginx(端口80)-->{Node_worker(端口3000)、Node_worker(端口3001)、Node_worker(端口3002)、Node_worker(端口3003)…}
可以说,单个端口设置有一些好处(可能会减少进程之间的耦合,有更复杂的负载平衡决策,等等),但设置起来肯定要做更多的工作,内置集群模块是一种低复杂性的替代方案,适用于大多数人