使用命令行的方式运行nodejs web应用,一旦程序有bug造成进程崩溃,应用就不能继续提供服务了;并且,nodejs是单线程的模式,不能充分利用服务器的多核资源。使用node的cluster模块可以监控应用进程,退出后重新启动node应用进程,并可以启动多个node应用进程,做到负载均衡,充分利用资源。
启动单个进程
node bin/www
文件www的内容为:
/**
* @fileOverview 应用程序启动文件入口
* @author --
*/
"use strict";
const app = require('../app');
const http = require('http');
const logger = require("../logger").appLogger();
/**
* 设置程序监听端口
*/
let port = normalizePort(config.port || process.env.PORT || '3001');
app.set('port', port);
/**
* 创建http服务实例
*/
let server = http.createServer(app);
/**
* 开启服务监听
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* 格式化监听端口
*/
function normalizePort(val) {
let port = parseInt(val, 10);
if (isNaN(port)) {
/** named pipe */
return val;
}
if (port >= 0) {
/** port number */
return port;
}
return false;
}
/**
* 启动错误事件处理
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
let bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
/** 错误提示 */
switch (error.code) {
case 'EACCES':
logger.error(bind + ' 权限不足');
process.exit(1);
break;
case 'EADDRINUSE':
logger.error(bind + ' 端口被占用');
process.exit(1);
break;
default:
throw error;
}
}
/**
* 正常启动事件处理
*/
function onListening() {
let addr = server.address();
let bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
logger.info('服务启动成功');
logger.info('Listening on ' + bind);
}
cluster多进程模式
node bin/cluster.js
文件cluster.js的内容为:
/**
* @fileOverview 应用程序多进程启动入口
* @author --
*/
"use strict";
const cluster = require('cluster');
const cpus = require('os').cpus();
const accessLogger = require("../logger").accessLogger();
accessLogger.info('master ' + process.pid + ' is starting.');
cluster.setupMaster({
/* 应用进程启动文件 */
exec: 'bin/www'
});
/* 启动应用进程个数和服务器CPU核数一样 */
for (let i = 0; i < cpus.length; i++) {
cluster.fork();
}
cluster.on('online', function (worker) {
/* 进程启动成功 */
accessLogger.info('worker ' + worker.process.pid + ' is online.');
});
cluster.on('exit', function (worker, code, signal) {
/* 应用进程退出时,记录日志并重启 */
accessLogger.info('worker ' + worker.process.pid + ' died.');
cluster.fork();
});
其他多进程方案
直接使用cluster模块管理nodejs进程,要在生产环境中使用,还要做很多工作,属于重复造轮子。现在比较流行的nodejs进程监控和多进程管理的工具有supervisor、forever、pm2等,下一篇将就pm2和docker谈一谈nodejs web应用在生产环境中的部署。