49

Node Cluster – Xieisabug

 6 years ago
source link: http://www.xiejingyang.com/2017/12/20/node-cluster-learning/?
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Node Cluster

于2017年12月20日由xiejingyang发布

众所周知,Nodejs是单线程运行的,这也是它经常被吐槽的一个点。针对这个点,Node推出了Cluster这个模块,用于创建多进程的Node应用。

Cluster的基本使用方法就是cluster.fork(),这样就能直接创建一个新的进程。进程使用有完全独立的数据空间,堆栈等。这个时候我们就有疑问了,既然是这个效果,那么我们为什么不自己fork呢?

Cluster不仅仅是fork出一个进程而已,它还帮我们管理了子进程,有通信机制,还有负载均衡等等功能,这些功能要自己实现的话,需要花费大量的工作量。

并且提一点,Cluster并不是fork的越多越好,Cluster是为了让Node利用起CPU的多核而设计的,所以Cluster fork的数量最好不要超过CPU的核数:

let cpus = require("os").cpus().length;

for (let i = 0; i < cpus; i++) {
    cluster.fork()
}

上面的代码就是创建和CPU核数相同数量的Cluster,但是这个时候子进程并没有业务处理,稍微加工一下上面的代码,就能有更多的业务了:

let cluster = require('cluster');
let http = require('http');
let numCPUs = require("os").cpus().length;

if (cluster.isMaster) {
    for (let i = 0; i < numCPUs; i++) {
        cluster.fork();
    }
} else {
    http.createServer(function(req, res) {
        res.writeHead(200);
        res.end('process ' + process.pid + ' says hello!');
    }).listen(8000);
}

我们创建了多个web服务器实例,并且共用了8000这一个端口,在访问的接口的时候,Cluster会用自己的负载均衡算法,将请求交给子进程处理。

最简单也是大家都能想到的一点,通过利用多核,Node的性能进一步的提高,这是一个对比的表格:

同时连接数 1 2 4 8 16
单进程 654 711 783 776 754
8进程 594 1198 2110 3010 3024

数据来自这里

还有一个显而易见的好处,就是可以做到零崩溃时间。因为在Cluster中的某个worker崩溃的时候,可以在Cluster的master中检测到,然后重启一个新的worker:

cluster.on('exit', function(worker, code, signal) {
    console.log('Worker ' + worker.process.pid + ' died with code: ' + code + ', and signal: ' + signal);
    console.log('Starting a new worker');
    cluster.fork();
});

单纯的评估改造量,要从代码写法和业务的角度来衡量,所以没办法统一评估。但我在这提到改造量,就是有其他的简洁改造方法。那就是PM2这个库。

PM2能够做到仅仅配置,而不需要改动我们的代码,就帮我们实现多进程启动。

安装了PM2之后,将启动程序的命令改为:pm2 start app.js -i 8,这样PM2就能用上CPU的8个核来跑我们的Node应用。PM2还有很多方便的命令,我就不一一介绍了,感兴趣的可以去这里了解。

那么,既然我们能直接使用PM2来直接实现多进程,还需要Cluster干什么呢?

因为PM2是不侵入我们的代码的,如果我们的业务需求有特殊性,就不能使用PM2了。

最典型的,就是有状态服务。

许多带有session的简单Node应用,在PM2的负载均衡下,很有可能出现session丢失的情况。还有一些socket应用,需要加入同一个房间,在同一个房间内存中共享了数据。这些应用都不能使用PM2,那么就需要我们自己使用Cluster来进行处理了。

Cluster能给Node带来性能上很大的提升,让Node以前让人诟病的单线程也得到解决了。同时,Cluster的多核利用,也能让我们发挥想象力,把它用在其他地方,比如编译打包,比如大数据处理等,以后也许能写出更好用的库。


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK