javascript代码实例教程-[Node.js] Cluster,把多核用起来

发布时间:2019-01-24 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了javascript代码实例教程-[Node.js] Cluster,把多核用起来脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
小宝典致力于为广大程序猿(媛)提供高品质的代码服务,请大家多多光顾小站,小宝典在此谢过。 引子

众所周知,虽然Node的底层有一个IO线程池,但其应用层默认是单线程运行的,对于多核CPU环境来说,是一种资的浪费。

 

所幸Node提供了child_PRocess 模块,让开发者得以开多个进程,实现每个进程各自利用一个CPU,以实现多核的利用。

 

child_process 模块给予Node 可以随意创建子进程的能力。因为 child_process 类本身是一个 EventEmITter,所以进程间通信很容易;且父子进程间通信并不通过网络层,而是在内核中完成,高效。

 

但 child_process 对于开发者来说,编程模型还是过于复杂,需要操心的细节过多,比如:父进程崩溃了,子进程回收是需要开发者提供代码来处理的——如果开发者只是想单纯利用多核模型,对具体工作进程的控制粒度并没有太多设想,那这种开发模型无疑是令人头疼的。

 

针对这个问题,Node 提供了 Cluster 模块。Cluster 简化了父子模型编程模型,只区分:当前进程是不是 Master,是 Master 就可以fork子进程,不是那就请行使Worker 职责。至于什么资源的回收,负载的调配,uncaughtException的处理,它自有安排。

 

本质上, Cluster 是 child_process 和 net 模块的组合应用。它不仅简化了编程模型,还使得共享监听同一端口成为可能。

 

更多关于Cluster的原理这里不表,感兴趣可以移步 → 解读Nodejs多核处理模块cluster

 

场景

用Node快速搭站呢,当然就用 exPress 咯 :) 所以,需求就是用 Cluster 做个单机集群,多进程跑 express,提升站点的吞吐量。

 

实验

先用 express-generator 搭个框子,模板引擎还是使 ejs 吧:

 

express -e myapp2

express-generator 默认会把 app.js 生成好,一行代码不写,一个完备的 http server 是已经实现的了。So,我们可以实现一个 Cluster 单机集群,clusterMaster.js:

 

复制代码

//CPU几核?

VAR cpus = require('os').cpus().length;

 

//子进程监听消息处理函数

var workerListener = function (msg) {

    if (msg.access)

        console.LOG('user access %s, worker [%d]', 

                           ;msg.access, msg.workerid);

};

//fork新的子进程函数

var forkWorker = function(listener){

    var worker = cluster.fork();

    console.log('worker [%d] has been created', 

                                 worker.process.pid);

    worker.on('message', listener);

    return worker;

};

 

//Cluster处理

var cluster = require('cluster');

if (cluster.isMaster) {

    for (var i = 0; i < cpus; i++) {

        forkWorker(workerListener);

    }

} else {

    var app = require('./app');

    return app.listen(3000);

}

 

//Cluster收到子进程退出消息

cluster.on('exit', function (worker, code, signal) {

    console.log('worker [%d] died %s, fork a new one.',

        worker.process.pid, code || signal);

    forkWorker(workerListener);

});

//Cluster收到子进程运行消息

cluster.on('online', function(worker){

    console.log('worker [%d] is running.', worker.process.pid);

});

复制代码

可以看到:

 

Cluster 是通过 isMaster 来区分父子进程的。父进程中处理创建逻辑:根据 CPU的核数,创建相应数量的子进程;子进程中运行具体的 Server 创建代码。够简单的模型~

在 Cluster 父进程端,是始终能获知 当前worker 的。而当前 worker 的 pid 呢,在有worker 句柄情况下,对应的是 woker.process.pid;在子进程运行的上下文中,就是 process.pid。这不难理解~

我们为新fork出来的子进程添加了消息处理函数,使得任何子进程运行代码,都可以随时利用消息触发它:用途挺广泛的,稍后会演示一个例子

在子进程退出时,Cluster 父进程会收到 exit 消息,这时会重fork一个新子进程来补缺

假设用户访问这个站点: localhost:3000/,我希望告诉他,是哪个子进程在为他渲染页面。那么,在 /routes/ 添加一个express 路由 index.js:

 

复制代码

var express = require('express');

var router = express.Router();

 

/* GET home page. */

router.get('/', function (req, res) {

    res.render('index', { title: 'Express', 

                              workerid: process.pid });

    process.send({access: '/', workerid: process.pid});

});

 

module.exports = router;

复制代码

可以看到,除了路由,还使用 process.send 发送了消息,它实际上会触发之前代码中子进程注册的 workerListener,向它汇报路径和进程号;由于使用了 render,那自然是少不了 ejs 模板, /views/index.js:

 

复制代码

<!DOCTYPE htML>

<html>

  <head>

    <title><%= title %></title>

    <link rel='stylesheet' href='/stylesheets/style.css' />

  </head>

  <body>

    <h1><%= title %></h1>

    <p>Welcome to <%= title %></p>

    <p>[<%= workerid %>] worker is serving for you.</p>

  </body>

</html>

复制代码

模板会将 render 携带的子进程 pid 渲染到页面上; 当然少不了在 app.js 中添加路由映射:

 

var routes = require('./routes/index');

 

app.use('/', routes);

觉得可用,就经常来吧! 脚本宝典 欢迎评论哦! js脚本,巧夺天工,精雕玉琢。小宝典献丑了!

脚本宝典总结

以上是脚本宝典为你收集整理的javascript代码实例教程-[Node.js] Cluster,把多核用起来全部内容,希望文章能够帮你解决javascript代码实例教程-[Node.js] Cluster,把多核用起来所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。