簡體   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