Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/469.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Node.js集群体系结构:如何扩展主工作者_Javascript_Node.js_Docker_Node Cluster - Fatal编程技术网

Javascript Node.js集群体系结构:如何扩展主工作者

Javascript Node.js集群体系结构:如何扩展主工作者,javascript,node.js,docker,node-cluster,Javascript,Node.js,Docker,Node Cluster,我已经构建了一个Node.js内置体系结构,具有主/辅配置。该应用程序使用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个worker,在master.js中有1个master。主程序和工作程序共享公共模块,而主程序有一个核心模块,该模块加载核心服务并在端口=300

我已经构建了一个Node.js内置体系结构,具有主/辅配置。该应用程序使用
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个worker,在
master.js
中有1个master。主程序和工作程序共享公共模块,而主程序有一个核心模块,该模块加载核心服务并在
端口=3001
上公开api,而工作程序则在已绑定Docker容器的
端口=3000
上加载其他api。当工作机上的路由代理将请求转发给主机以向核心模块提供请求时,其他请求将直接发送给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);
“严格使用”;
(功能(){
///节点聚类
const cluster=require('cluster');
const numpus=require('os').cpus().length;
if(cluster.isMaster){//master节点
var masterConfig=require('./config/masterConfig.json');
//叉工。
var maxCPUs=process.env.WORKER_NUM | | masterConfig.cluster.WORKER.NUM;
MAXCPU=(MAXCPU>NUMCPU)?NUMCPU:MAXCPU;
for(设i=0;i{
log(`Master${process.pid}在${masterConfig.pubsub.node}上运行);
})
.catch(错误=>{//无法从主错误恢复
错误(`Master${process.pid}error`,error.stack);
过程。退出(1);
});
}
else if(cluster.isWorker){//worker节点
var workerConfig=require('./config/workerConfig.json');
var WorkerNode=require('./lib/worker');
var worker=新WorkerNode(workerConfig);
worker.start()
。然后(完成=>{
log(`Worker${process.pid}在${workerConfig.pubsub.node}上运行);
})
.catch(错误=>{//worker错误是可恢复的
错误(`Worker${process.pid}error`,error.stack);
});
}
}).打电话(这个);
我有以下问题

1) 默认情况下,
集群
模块共享下面的HTTP连接使用一种方法来服务请求-请参阅,其中工作进程是使用。我不知道是否可以自定义此方法来分发传入连接

2) 到目前为止,我在expressweb应用程序中为
PORT=3000
上的每个Worker提供静态文件和模板(如pig/swig),这意味着我在生成的每个Worker实例上运行web应用程序的静态路由。我不确定在内存占用方面,这是否是最好的方法


3) 其他聚类方法。我曾询问过如何将此体系结构迁移到PM2,尽管它似乎很有希望,但我不确定它是否是最佳选择-有关更多详细信息,请参阅。

主机只应关心启动工人并正确关闭工人/注意主机的信号并做出相应的响应。根据我的经验,我遇到了一些棘手的bug,因为我在主应用程序上暴露了一个API,而该API应该在工作程序上

如果您计划切换到PM2,PM2将处理您的主代码,并且您无论如何都需要将该代码移动到工作者(或者至少是以前的情况)

关于你的问题,

  • 如果您需要覆盖循环或自定义循环,我认为您的目标是将相同的客户端流量路由到相同的工作进程,即粘性会话。但也有局限性;如果您在节点前面使用反向代理,如nginx或haproxy(您应该这样做),并且还希望套接字按预期工作(并且在游戏中有Docker),那么您不能真正在workers上展开,因为您看到的IP(您将在其上计算粘性会话id)将始终是您的代理或Docker主机的IP(即使使用x-forwarded-for-header),这首先就违背了集群的目的。 ->我的解决方案是在一个新端口(例如3001、3002…300N)上启动每个worker,并让nginx处理粘性会话处理
  • 这不是一个问题,但并不理想——是的,内存会略有增加,因为每个工作进程都会加载路由和模块。但nginx在处理静态文件(以及处理带有许多http头的缓存)方面比node快得多。因此,您应该依赖nginx提供静态服务,并让node处理动态请求(如/api/login等)
  • PM2是一个很好的解决方案,它具有许多高级功能,如报告统计数据和处理零停机部署,但也会根据您想要使用的功能而增加成本

  • 谢谢。关于第2点,我忘了提到我实际上是在为一个web应用程序(模板、登录等)服务,所以这不仅仅是静态的东西,这就是为什么我对API和WebApp都使用express的原因。@loretoparisi这不是问题!您可以对静态文件使用nginx(在/img/css/js/font等下的所有内容)如果你正在从模板中生成HTML,请考虑用Gruntjs/Gulpjs/WebPACK构建一个构建步骤,这样你就可以用NGNIX服务这些文件了。