1. 程式人生 > 程式設計 >Nodejs-cluster模組知識點總結及例項用法

Nodejs-cluster模組知識點總結及例項用法

面試官有時候會問你,你給我說下node如何開啟多程序哇,你腦海裡就應該立刻出現cluster模組,如今讓我帶你去探討下cluster模組的使用。

基本用法

Node.js預設單程序執行,對於32位系統最高可以使用512MB記憶體,對於64位最高可以使用1GB記憶體。對於多核CPU的計算機來說,這樣做效率很低,因為只有一個核在執行,其他核都在閒置。cluster模組就是為了解決這個問題而提出的。

cluster模組允許設立一個主程序和若干個worker程序,由主程序監控和協調worker程序的執行。worker之間採用程序間通訊交換訊息,cluster模組內建一個負載均衡器,採用Round-robin演算法hsOVv

協調各個worker程序之間的負載。執行時,所有新建立的連結都由主程序完成,然後主程序再把TCP連線分配給指定的worker程序。

var cluster = require('cluster');
var os = require('os');

if (cluster.isMaster){
for (var i = 0,n = os.cpus().length; i < n; i += 1){
cluster.fork();
}
} else {
http.createServer(function(req,res) {
res.writeHead(200);
res.end("hello world\n");
}).listen(8000);
}

上面程式碼先判斷當前程序是否為主程序(cluster.isMaster),如果是的,就按照CPU的核數,新建若干個worker程序;如果不是,說明當前程序是worker程序,則在該程序啟動一個伺服器程式。

上面這段程式碼有一個缺點,就是一旦work程序掛了,主程序無法知道。為了解決這個問題,可以在主程序部署online事件和exit事件的監聽函式。

var cluster = require('cluster');
 
if(cluster.isMaster) {
  var numWorkers = require('os').cpus().length;
  console.log('Master cluster setting up ' + numWorkers + ' workers...');
 
  for(var i = 0; i < numWorkers; i++) {
    cluster.fork();
  }
 
  cluster.on('online',function(worker) {
    console.log('Worker ' + worker.process.pid + ' is online');
  });
 
  cluster.on('exit',function(worker,code,signal) {
    console.log('Worker ' + worker.process.pidhttp://www.cppcns.com
+ ' died with code: ' + code + ',and signal: ' + signal); console.log('Starting a new worker'); cluster.fork(); }); }

上面程式碼中,主程序一旦監聽到worker程序的exit事件,就會重啟一個worker程序。worker程序一旦啟動成功,可以正常運行了,就會發出online事件。

worker物件

worker物件是cluster.fork()的返回值,代表一個worker程序。

它的屬性和方法如下。

(1)worker.id

worker.id返回當前worker的獨一無二的程序編號。這個編號也是cluster.workers中指向當前程序的索引值。

(2)worker.process

所有的worker程序都是用child_process.fork()生成的。child_process.fork()返回的物件,就被儲存在worker.process之中。通過這個屬性,可以獲取worker所在的程序物件。

(3)worker.send()

該方法用於在主程序中,向子程序傳送資訊。

if (cluster.isMaster) {
  var worker = cluster.fork();
  worker.send('hi there');
} else if (cluster.isWorker) {
  process.on('message',function(msg) {
    process.send(msg);
  });
}

上面程式碼的作用是,worker程序對主程序發出的每個訊息,都做回聲。

在worker程序中,要向主程序傳送訊息,使用process.send(message);要監聽主程序發出的訊息,使用下面的程式碼。

process.on('message',function(message) {
  console.log(message);
});

發出的訊息可以字串,也可以是JSON物件。下面是一個傳送JSON物件的例子。

worker.send({
  type: 'task 1',from: 'master',data: {
    // the data that you want to transfer
  }
});

cluster.workers物件

該物件只有主程序才有,包含了所有worker程序。每個成員的鍵值就是一個worker程序物件,鍵名就是該worker程序的worker.id屬性。

socket.on('data',function(id) {
  var worker = cluster.workers[id];
});

cluster模組的屬性與方法

isMaster,isWorker

isMaster屬性返回一個布林值,表示當前程序是否為主程序。這個屬性由process.env.NODE_UNIQUE_ID決定,如果process.env.NODE_UNIQUE_ID為未定義,就表示該程序是主程序。

isWorker屬性返回一個布林值,表示當前程序是否為work程序。它與isMaster屬性的值正好相反。

fork()

fork方法用於新建一個worker程序,上下文都複製主程序。只有主程序才能呼叫這個方法。

該方法返回一個worker物件。

kill()

kill方法用於終止worker程序。它可以接受一個引數,表示系統訊號。

如果當前是主程序,就會終止與worker.process的聯絡,然後將系統訊號法發向worker程序。如果當前是worker程序,就會終止與主程序的通訊,然後退出,返回0。

在以前的版本中,該方法也叫做 worker.destroy() 。

listening事件

worker程序呼叫listening方法以後,“listening”事件就傳向該程序的伺服器,然後傳向主程序。

該事件的回撥函式接受兩個引數,一個是當前worker物件,另一個是地址物件,包含網址、埠、地址型別(IPv4、IPv6、Unix socket、UDP)等資訊。這對於那些服務多個網址的Node應用程式非常有用。

不中斷地重啟Node服務

重啟服務需要關閉後再啟動,利用cluster模組,可以做到先啟動一個worker程序,再把原有的所有work程序關閉。這樣就能實現不中斷地重啟Node服務。

首先,主程序向worker程序發出重啟訊號。

workers[wid].send({type: 'shutdown',from: 'master'});

worker程序監聽message事件,一旦發現內容是shutdown,就退出。

process.on('message',function(message) {
  if(message.type === 'shutdown') {
    process.exit(0);
  }
});

下面是一個關閉所有worker程序的函式。

function restartWorkers() {
 客棧 var wid,workerIds = [];
  for(wid in cluster.workers) {
    workerIds.push(wid);
  }
 
  workerIds.forEach(function(wid) {
    cluster.workers[wid].send({
      text: 'shutdown',from: 'master'
     });
    setTimeout(function() {
      if(cluster.workers[wid]) {
        cluster.workers[wid].kill('SIGKILL');
      }
    },5000);
  });
};

PM2模組

PM2模組是cluster模組的一個包裝層。它的作用是儘量將cluster模組抽象掉,讓使用者像使用單程序一樣,部署多程序Node應用。

// app.js
var http = require('http');
 
http.createServer(function(req,res) {
  res.writeHead(200);
  res.end("hello world");
}).listen(8080);

用PM2從命令列啟動這段程式碼

$ pm2 start app.js -i 4

上面程式碼的i引數告訴PM2,這段程式碼應該在cluster_mode啟動,且新建worker程序的數量是4個。如果i引數的值是0,那麼當前機器有幾個CPU核心,PM2就會啟動幾個worker程序。

如果一個worker程序由於某種原因掛掉了,會立刻重啟該worker程序。

# 重啟所有worker程序
$ pm2 relo程式設計客棧ad all

每個worker程序都有一個id,可以用下面的命令檢視單個worker程序的詳情。

$ pm2 show <worker id>

關閉worker程序的時候,可以部署下面的程式碼,讓worker程序監聽shutdown訊息。一旦收到這個訊息,進行完畢收尾清理工作再關閉

process.on('message',function(msg) {
  if (msg === 'shutdown') {
    close_all_connections();
    delete_logs();
    server.close();
    process.exit(0);
  }
});

到此這篇關於Nodejs-cluster模組知識點總結及例項用法的文章就介紹到這了,更多相關Nodejs-cluster模組介紹內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!