在Expressjs应用程序中使用群集

我在我的第一个节点项目上做了一点OJT,虽然我可以站起来一个简单的服务器,但是应用程序将会受到打击,所以使用集群似乎是一个好主意。 我拼凑了一些我在各种search(包括SO)中find的代码片段,但是服务器不会启动。 我敢肯定,我对节点的经验不足让我做了一些愚蠢的事情,但是我看不到它。

var express = require( 'express' ); var cluster = require( 'cluster' ); var path = require( 'path' ); var cCPUs = require( 'os' ).cpus().length; var port = 3000; var root = path.dirname( __dirname ); if( cluster.isMaster ) { for( var i = 0; i < cCPUs; i++ ) { cluster.fork(); } cluster.on( 'death', function( worker ) { console.log( 'Worker ' + worker.pid + ' died.' ); }); } else { // eyes.inspect( process.env ); console.log( 'Worker: %s', process.env.NODE_WORKER_ID ); var app = express(); var routes = require( './routes' )( app ); app .use( cluster.repl( root + 'cluster.repl' ) ) .use( cluster.stats({ connections: true, requests: true }) ) .use( cluster.reload( root ) ) .listen( port ); } 

结果:

 TypeError: Object #<Cluster> has no method 'repl' 

如果我删除use调用,工作人员启动正确,但process.env.NODE_WORKER_IDundefined 。 检查process.env告诉我,它绝对没有定义。 也许我使用的片段是从旧版本,但我不知道如何识别工作线程以任何其他方式。

如果任何人都能解开乱七八糟的,我真的很感激。

对于以后search的人来说,这就是我最终的结果:

 var cluster = require( 'cluster' ); var express = require( 'express' ); var path = require( 'path' ); var port = 3000; var root = path.dirname( __dirname ); var cCPUs = require('os').cpus().length; if( cluster.isMaster ) { // Create a worker for each CPU for( var i = 0; i < cCPUs; i++ ) { cluster.fork(); } cluster.on( 'online', function( worker ) { console.log( 'Worker ' + worker.process.pid + ' is online.' ); }); cluster.on( 'exit', function( worker, code, signal ) { console.log( 'worker ' + worker.process.pid + ' died.' ); }); } else { var app = express(); var routes = require( './routes' )( app ); app .use( express.bodyParser() ) .listen( port ); } 

我在节点学习曲线上还很早,但是服务器启动并且似乎在每个内核上都有工作。 感谢JohnnyH让我走上正轨。

另外看看cluster2 。 它被易趣使用,并有一个明确的例子

 var Cluster = require('cluster2'), express = require('express'); var app = express.createServer(); app.get('/', function(req, res) { res.send('hello'); }); var c = new Cluster({ port: 3000, }); c.listen(function(cb) { cb(app); }); 

这是我的Cluster.js类的草稿。 请注意,当您启动主进程时,我们应该捕获端口冲突。

 /*jslint indent: 2, node: true, nomen: true, vars: true */ 'use strict'; module.exports = function Cluster(options, resources, logger) { var start = function () { var cluster = require('cluster'); if (cluster.isMaster) { require('portscanner').checkPortStatus(options.express.port, '127.0.0.1', function (error, status) { if (status === 'open') { logger.log.error('Master server failed to start on port %d due to port conflict', options.express.port); process.exit(1); } }); // Each core to run a single process. // Running more than one process in a core does not add to the performance. require('os').cpus().forEach(function () { cluster.fork(); }); cluster.on('exit', function (worker, code, signal) { logger.log.warn('Worker server died (ID: %d, PID: %d)', worker.id, worker.process.pid); cluster.fork(); }); } else if (cluster.isWorker) { var _ = require('underscore'); var express = require('express'); var resource = require('express-resource'); // Init App var app = express(); // App Property app.set('port', process.env.PORT || options.express.port); app.set('views', options.viewPath); app.set('view engine', 'jade'); app.set('case sensitive routing', true); app.set('strict routing', false); // App Middleware app.use(express.favicon(options.faviconPath)); app.use(express.logger({ stream: logger.stream() })); app.use(express.bodyParser()); app.use(express.methodOverride()); app.use(express.responseTime()); app.use(app.router); app.use(require('stylus').middleware(options.publicPath)); app.use(express['static'](options.publicPath)); if (options.express.displayError) { app.use(express.errorHandler()); } // App Format app.locals.pretty = options.express.prettyHTML; // App Route Handler if (!_.isUndefined(resources) && _.isArray(resources)) { _.each(resources, function (item) { if (!_.isUndefined(item.name) && !_.isUndefined(item.path)) { app.resource(item.name, require(item.path)); } }); } // Start Server var domain = require('domain').create(); domain.run(function () { require('http').createServer(app).listen(app.get('port'), function () { logger.log.info('Worker server started on port %d (ID: %d, PID: %d)', app.get('port'), cluster.worker.id, cluster.worker.process.pid); }); }); domain.on('error', function (error) { logger.log.error(error.stack); }); } }; return { start: start }; };