如何在 Express Generator App Skeleton 中使用 Node Cluster 模块
Posted
技术标签:
【中文标题】如何在 Express Generator App Skeleton 中使用 Node Cluster 模块【英文标题】:How to Use Node Cluster module within Express Generator App Skeleton 【发布时间】:2016-04-24 10:08:44 【问题描述】:我正在尝试在我的 Express 应用中使用集群模块。我使用 express-generator 创建我的应用程序结构,但我不确定如何在保持 app.js 和 bin/www 分离的同时合并集群模块。我已经看过使用 express 的集群的教程和 github 示例,但在完整的应用程序框架中没有。有没有办法在合并集群模块的同时保持 app.js 和 www 的分离?
这是我的完整 bin/www 文件:
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('football:server');
var http = require('http');
var cluster = require('cluster');
var numCPUs = require('os').cpus().length;
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
if(cluster.isMaster)
// Fork workers.
for (var i = 0; i < numCPUs; i++)
console.log('forking process', i)
cluster.fork();
// If a worker dies, log it to the console and start another worker.
cluster.on('exit', function(worker, code, signal)
console.log('Worker ' + worker.process.pid + ' died.');
cluster.fork();
);
// Log when a worker starts listening
cluster.on('listening', function(worker, address)
console.log('Worker started with PID ' + worker.process.pid + '.');
);
else
/**
* Create HTTP server.
*/
console.log('i am in the else statement')
var server = http.createServer(app);
console.log('created another server')
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val)
var port = parseInt(val, 10);
if (isNaN(port))
// named pipe
return val;
if (port >= 0)
// port number
return port;
return false;
/**
* Event listener for HTTP server "error" event.
*/
function onError(error)
if (error.syscall !== 'listen')
throw error;
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code)
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
/**
* Event listener for HTTP server "listening" event.
*/
function onListening()
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
console.log('yay')
我从来没有收到说“Worker 正在使用 pid 侦听...”的消息,并且 else 语句顶部的 console.log() 从来没有被打印出来。
【问题讨论】:
【参考方案1】:这是具有集群支持的完整 express-generator bin/www 文件:
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var cluster = require('cluster');
var debug = require('debug')('temp:server');
var http = require('http');
var numCPUs = require('os').cpus().length;
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
if (cluster.isMaster)
// Fork workers.
for (var i = 0; i < numCPUs; i++)
cluster.fork();
// If a worker dies, log it to the console and start another worker.
cluster.on('exit', function(worker, code, signal)
console.log('Worker ' + worker.process.pid + ' died.');
cluster.fork();
);
// Log when a worker starts listening
cluster.on('listening', function(worker, address)
console.log('Worker started with PID ' + worker.process.pid + '.');
);
else
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
// The rest of the bin/www file.....
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val)
var port = parseInt(val, 10);
if (isNaN(port))
// named pipe
return val;
if (port >= 0)
// port number
return port;
return false;
/**
* Event listener for HTTP server "error" event.
*/
function onError(error)
if (error.syscall !== 'listen')
throw error;
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code)
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
/**
* Event listener for HTTP server "listening" event.
*/
function onListening()
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
您应该可以将此文件用作现有 bin/www 文件的替代品。无需对现有应用程序或第三方模块进行其他更改。
【讨论】:
我把它放到了我的 bin/www 中,但我从来没有收到消息说“Worker 以 pid 开始...”我在 else 语句的顶部放置了一个 console.log() 并且没有被打印。你知道为什么永远不会触发 else 语句吗? 你在什么环境下运行?操作系统/节点版本。 我正在使用 cloud 9,它是一个带有 Docker 容器的 ubuntu 操作系统。我认为这是他们的调试器和/或应用程序运行器的问题。以上是关于如何在 Express Generator App Skeleton 中使用 Node Cluster 模块的主要内容,如果未能解决你的问题,请参考以下文章
在 express-generator 中使用 bin 文件而不是 .js 的好处