多处理器上的 NodeJS(PM2、Cluster、Recluster、Naught)
NodeJS on multiple processors (PM2, Cluster, Recluster, Naught)
我正在研究 运行 节点在多核环境中的选项。
我正在尝试确定最佳方法,到目前为止我已经看到了这些选项
- 使用内置的集群库启动工作并响应信号
- 使用 PM,但是 PM2 -i 被列为测试版。
- 无
- 重新集群
还有其他选择吗?人们在生产中使用什么?
我一直在使用默认的集群库,效果很好。我有超过 10,000 个并发(多个服务器上的多个集群)并且它工作得很好。
错误处理建议使用带域的集群
这是直接从 http://nodejs.org/api/domain.html 中提取的,我对它如何为机器的每个核心生成新集群做了一些更改。并删除了 if/else 并添加了 express.
var cluster = require('cluster'),
http = require('http'),
PORT = process.env.PORT || 1337,
os = require('os'),
server;
function forkClusters () {
var cpuCount = os.cpus().length;
// Create a worker for each CPU
for (var i = 0; i < cpuCount ; i += 1) {
cluster.fork();
}
}
// Master Process
if (cluster.isMaster) {
// You can also of course get a bit fancier about logging, and
// implement whatever custom logic you need to prevent DoS
// attacks and other bad behavior.
//
// See the options in the cluster documentation.
//
// The important thing is that the master does very little,
// increasing our resilience to unexpected errors.
forkClusters ()
cluster.on('disconnect', function(worker) {
console.error('disconnect!');
cluster.fork();
});
}
function handleError (d) {
d.on('error', function(er) {
console.error('error', er.stack);
// Note: we're in dangerous territory!
// By definition, something unexpected occurred,
// which we probably didn't want.
// Anything can happen now!Be very careful!
try {
// make sure we close down within 30 seconds
var killtimer = setTimeout(function() {
process.exit(1);
}, 30000);
// But don't keep the process open just for that!
killtimer.unref();
// stop taking new requests.
server.close();
// Let the master know we're dead.This will trigger a
// 'disconnect' in the cluster master, and then it will fork
// a new worker.
cluster.worker.disconnect();
} catch (er2) {
// oh well, not much we can do at this point.
console.error('Error sending 500!', er2.stack);
}
});
}
// child Process
if (cluster.isWorker) {
// the worker
//
// This is where we put our bugs!
var domain = require('domain');
var express = require('express');
var app = express();
app.set('port', PORT);
// See the cluster documentation for more details about using
// worker processes to serve requests.How it works, caveats, etc.
var d = domain.create();
handleError(d);
// Now run the handler function in the domain.
//
// put all code here. any code included outside of domain.run will not handle errors on the domain level, but will crash the app.
//
d.run(function() {
// this is where we start our server
server = http.createServer(app).listen(app.get('port'), function () {
console.log('Cluster %s listening on port %s', cluster.worker.id, app.get('port'));
});
});
}
我们使用 Supervisor 来管理我们的 Node.JS 进程,在启动时启动它们,并在进程崩溃时充当看门狗。
我们使用 Nginx 作为反向代理来负载平衡侦听不同端口的进程之间的流量
这样每个进程都相互隔离。
例如:Nginx监听80端口,转发流量到8000-8003端口
我使用 PM2 已经有一段时间了,但它们的定价对我的需求来说太贵了,因为我有自己的分析环境而且我不需要支持,所以我决定试验替代方案。对于我的情况,只是永远成功了,实际上非常简单:
forever -m 5 app.js
另一个有用的例子是
forever start app.js -p 8080
我正在研究 运行 节点在多核环境中的选项。
我正在尝试确定最佳方法,到目前为止我已经看到了这些选项
- 使用内置的集群库启动工作并响应信号
- 使用 PM,但是 PM2 -i 被列为测试版。
- 无
- 重新集群
还有其他选择吗?人们在生产中使用什么?
我一直在使用默认的集群库,效果很好。我有超过 10,000 个并发(多个服务器上的多个集群)并且它工作得很好。
错误处理建议使用带域的集群
这是直接从 http://nodejs.org/api/domain.html 中提取的,我对它如何为机器的每个核心生成新集群做了一些更改。并删除了 if/else 并添加了 express.
var cluster = require('cluster'),
http = require('http'),
PORT = process.env.PORT || 1337,
os = require('os'),
server;
function forkClusters () {
var cpuCount = os.cpus().length;
// Create a worker for each CPU
for (var i = 0; i < cpuCount ; i += 1) {
cluster.fork();
}
}
// Master Process
if (cluster.isMaster) {
// You can also of course get a bit fancier about logging, and
// implement whatever custom logic you need to prevent DoS
// attacks and other bad behavior.
//
// See the options in the cluster documentation.
//
// The important thing is that the master does very little,
// increasing our resilience to unexpected errors.
forkClusters ()
cluster.on('disconnect', function(worker) {
console.error('disconnect!');
cluster.fork();
});
}
function handleError (d) {
d.on('error', function(er) {
console.error('error', er.stack);
// Note: we're in dangerous territory!
// By definition, something unexpected occurred,
// which we probably didn't want.
// Anything can happen now!Be very careful!
try {
// make sure we close down within 30 seconds
var killtimer = setTimeout(function() {
process.exit(1);
}, 30000);
// But don't keep the process open just for that!
killtimer.unref();
// stop taking new requests.
server.close();
// Let the master know we're dead.This will trigger a
// 'disconnect' in the cluster master, and then it will fork
// a new worker.
cluster.worker.disconnect();
} catch (er2) {
// oh well, not much we can do at this point.
console.error('Error sending 500!', er2.stack);
}
});
}
// child Process
if (cluster.isWorker) {
// the worker
//
// This is where we put our bugs!
var domain = require('domain');
var express = require('express');
var app = express();
app.set('port', PORT);
// See the cluster documentation for more details about using
// worker processes to serve requests.How it works, caveats, etc.
var d = domain.create();
handleError(d);
// Now run the handler function in the domain.
//
// put all code here. any code included outside of domain.run will not handle errors on the domain level, but will crash the app.
//
d.run(function() {
// this is where we start our server
server = http.createServer(app).listen(app.get('port'), function () {
console.log('Cluster %s listening on port %s', cluster.worker.id, app.get('port'));
});
});
}
我们使用 Supervisor 来管理我们的 Node.JS 进程,在启动时启动它们,并在进程崩溃时充当看门狗。
我们使用 Nginx 作为反向代理来负载平衡侦听不同端口的进程之间的流量
这样每个进程都相互隔离。
例如:Nginx监听80端口,转发流量到8000-8003端口
我使用 PM2 已经有一段时间了,但它们的定价对我的需求来说太贵了,因为我有自己的分析环境而且我不需要支持,所以我决定试验替代方案。对于我的情况,只是永远成功了,实际上非常简单:
forever -m 5 app.js
另一个有用的例子是
forever start app.js -p 8080