我已经使用主/工作人员配置构建了Node.js内置cluster架构。该应用程序正在使用express
来提供api和静态文件,并与Docker一起部署:
[D O C K E R: 8080] --- N ---> [W O R K E R: 3001 ] --- 1 ---> [M A S T E R: 3000]
我在Worker.js
中有N个工人,在master.js
中有1个主人。主服务器和工作服务器共享通用模块,而主服务器有一个核心模块,该模块可以加载核心服务并在PORT=3001
上公开一个api,而工作服务器则在PORT=3000
上将其他api加载到已绑定了Docker容器的地方。虽然工作服务器上的路由代理会将请求转发到主服务器,以便将请求服务到核心模块,但其他请求则直接在3000上作为服务器。
启动脚本看起来像
'use strict';
(function() {
/// node clustering
const cluster = require('cluster');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) { // master node
var masterConfig=require('./config/masterconfig.json');
// Fork workers.
var maxCPUs = process.env.WORKER_NUM || masterConfig.cluster.worker.num;
maxCPUs=(maxCPUs>numCPUs)?numCPUs:maxCPUs;
for (let i = 0; i < maxCPUs; i++) {
const worker=cluster.fork();
}
var MasterNode=require('./lib/master');
var master= new MasterNode(masterConfig);
master.start()
.then(done=> {
console.log(`Master ${process.pid} running on ${masterConfig.pubsub.node}`);
})
.catch(error=> { // cannot recover from master error
console.error(`Master ${process.pid} error`,error.stack);
process.exit(1);
});
}
else if (cluster.isWorker) { // worker node
var workerConfig=require('./config/workerconfig.json');
var WorkerNode=require('./lib/worker');
var worker= new WorkerNode(workerConfig);
worker.start()
.then(done=> {
console.log(`Worker ${process.pid} running on ${workerConfig.pubsub.node}`);
})
.catch(error=> { // worker error is recoverable
console.error(`Worker ${process.pid} error`,error.stack);
});
}
}).call(this);
我有以下问题。
1)默认情况下,cluster
模块共享带下划线的HTTP连接,使用round-robin方法处理请求-请参见here,其中使用child_process.fork()生成工作进程。我不知道是否可以自定义此方法来分配传入的连接。
2)到目前为止,我在PORT=3000
的每个Worker上的快速Web应用程序中提供静态文件,模板(例如pig / swig),这意味着我在每个worker实例上为该Web应用程序运行了静态路由产生。就内存占用而言,我不确定这是否是最佳方法。
3)其他聚类方法。我曾问过有关将这种体系结构迁移到PM2的问题,尽管它似乎很有前途,但我不确定它是否是最佳选择-有关更多详细信息,请参见here。
答案 0 :(得分:3)
主机只应关心启动工作程序并正确关闭它们/当心来自主机的信号并作出相应响应。根据我的经验,我遇到了一些棘手的错误,因为我在主服务器上公开了应该由工作人员使用的API。
如果您打算切换到PM2,则PM2将处理您的主服务器,并且无论如何(或者至少以前是这种情况),您都需要将该代码移交给工作人员
关于您的问题;