参照《nodejs开发指南》(node版本 v0.8.16)
创建一个服务器,实现一个简单功能:记录用户请求数(node app.js进入调试模式)
var http = require('http'); var tag = 0 //exports.tag = tag //module.exports.listen = function(port){ exports.listen = function startServer(port){ // create http server var server = http.createServer(function (req, res) { // content header res.writeHead(200, {'content-type': 'text/plain'}); // write message and signal communication is complete tag ++ res.end("Hello, Visitor " + tag + "! I'm server " + process.pid + "\n"); if (process && process.send) { process.send({ cmd: 'notifyRequest' }); } }); if (!module.parent) { console.log('Server debugging on '+ port +'/'); server.listen(port); } else { console.log('Server running on '+ port +'/'); server.listen(port); } } if (!module.parent) { this.listen(8124) }
使用cluster模块,开启多个进程共享服务端口,充分利用多核优势(node cluster.js进入生产环境)
var cluster = require('cluster'); var os = require('os'); // 获取CPU 的数量,让node进程数和cpu数目一致,充分均摊负载。 var numCPUs = os.cpus().length; var workers = {}; //console.log('numCPU = ' + numCPUs) if (cluster.isMaster) { var g_tag = 0 // 主进程分支 cluster.on('death', function (worker) { // 当一个工作进程结束时,重启工作进程 delete workers[worker.pid]; worker = cluster.fork(); workers[worker.pid] = worker; }); // 初始开启与CPU 数量相同的工作进程 numCPUs = 4// 如果进程数多余cpu数目,进程处理请求将不均衡 for (var i = 0; i < numCPUs; i++) { var worker = cluster.fork(); worker.on('message', function(msg) { if (msg.cmd && msg.cmd == 'notifyRequest') { g_tag++; console.log('Visitor Total : %d ', g_tag); } }); workers[worker.pid] = worker; } cluster.on('exit', function(worker, code, signal) { //每一个worker出错或者被kill掉时重启一个新worker console.log(worker.process.pid + " is no more running") process.nextTick(function () { //避免cpu负载过高,定时重启 var worker = cluster.fork(); worker.on('message', function(msg) { if (msg.cmd && msg.cmd == 'notifyRequest') { g_tag++; console.log('Visitor Total : %d ', g_tag); } }); workers[worker.pid] = worker; }); }); } else { // 工作进程分支,启动服务器 var app = require('./app'); //console.log(app.tag) //如果需要访问此变量需要将它export,不然是undefined app.listen(3000); } // 当主进程被终止时,关闭所有工作进程 process.on('SIGTERM', function () { for (var pid in workers) { process.kill(pid); } process.exit(0); });
运行如下:
[root@ ~]# node cluster.js Server running on 3000/ Server running on 3000/ Server running on 3000/ Server running on 3000/ [root@ ~]# ps -ef | grep node root 7587 1334 0 06:28 pts/1 00:00:00 node cluster.js root 7589 7587 0 06:28 pts/1 00:00:00 /usr/local/node/bin/node /root/cluster.js root 7590 7587 0 06:28 pts/1 00:00:00 /usr/local/node/bin/node /root/cluster.js root 7591 7587 0 06:28 pts/1 00:00:00 /usr/local/node/bin/node /root/cluster.js root 7592 7587 0 06:28 pts/1 00:00:00 /usr/local/node/bin/node /root/cluster.js root 7598 1343 0 06:29 pts/2 00:00:00 grep node
其中app.js中tag是worker各个进程内存,无法共享,g_tag通过events同步数据
结合forever模块,可以使程序后台运行
最简单的办法: $ nohup node app.js & forever能做更多的事情,比如分别记录输出和错误日志,比如可以在js中作为api使用。 $ sudo npm install forever -g #安装 $ forever start app.js #启动 $ forever stop app.js #关闭 $ forever start -l forever.log -o out.log -e err.log app.js #输出日志和错误
注:如果要引用require('app'),则需要把app.js放到node_modules目录下