繁体   English   中英

Node.js集群架构:如何扩展主工作者

[英]Node.js Cluster architecture: how to scale master worker

我已经构建了一个具有主/工配置的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]

我有在N-工人Worker.js和在1个主master.js 主服务器和工作器共享通用模块,而主服务器有一个核心模块,用于加载核心服务并在PORT=3001上公开api,工作人员在PORT=3000上加载另一个api,Docker容器已经绑定。 虽然Worker上的路由代理会将请求转发给Master以便向核心模块提供请求,但其他请求直接是服务器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连接使用循环方法来处理请求 - 请参阅此处 ,其中使用child_process.fork()生成工作进程。 我不知道我是否可以自定义此方法来分配传入连接。

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

3)其他聚类方法。 我已经问过将这个架构迁移到PM2,尽管看起来很有希望,我不确定它是最好的选择 - 请看这里了解更多细节。

主人应该只关心启动工人并正确关闭他们/注意来自主人的信号并做出相应的响应。 根据我的经验,我遇到了棘手的错误,因为我在主服务器上暴露了应该在工作者身上的API。

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

关于你的问题;

  1. 如果您需要覆盖循环或自定义循环,我认为您的目标是将相同的客户端流量路由到同一个工作人员,即Sticky Sessions。 有办法,但有一些限制; 如果你在节点前面使用像nginx或haproxy这样的反向代理(你应该)并且也希望套接字按预期工作(并且在游戏中有Docker),你就不能真正地对工作人员展开,因为你看到了IP (您将在其上计算粘性会话ID)将始终是您的代理或Docker主机之一(即使使用x-forwarded-for标头),这首先会破坏集群的目的。 - >我的解决方案是在一个新端口上启动每个worker(例如3001,3002 ... 300N)并让nginx处理粘性会话处理
  2. 这不是问题,但并不理想 - 是的,内存会略微上升,因为每个工作人员都会加载路由和模块。 但是nginx在处理静态文件(以及使用许多http-header处理缓存)方面比节点更快。 所以你应该依赖nginx服务静态并保持节点的动态请求(比如/ api / login等)
  3. PM2是一个很好的解决方案,具有许多高级功能,如报告统计信息和处理零停机时间部署,但也需要花钱,具体取决于您要使用哪些功能

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM