最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談nodejs中創(chuàng)建cluster

 更新時間:2021年06月03日 10:37:53   作者:flydean  
集群是一組相互獨立的、通過高速網(wǎng)絡(luò)互聯(lián)的計算機(jī),它們構(gòu)成了一個組,并以單一系統(tǒng)的模式加以管理。一個客戶與集群相互作用時,集群像是一個獨立的服務(wù)器。集群配置是用于提高可用性和可縮放性。本文將詳細(xì)介紹如何在nodejs中創(chuàng)建cluster。

cluster集群

我們知道,nodejs的event loop或者說事件響應(yīng)處理器是單線程的,但是現(xiàn)在的CPU基本上都是多核的,為了充分利用現(xiàn)代CPU多核的特性,我們可以創(chuàng)建cluster,從而使多個子進(jìn)程來共享同一個服務(wù)器端口。

也就是說,通過cluster,我們可以使用多個子進(jìn)程來服務(wù)處理同一個端口的請求。

先看一個簡單的http server中使用cluster的例子:

const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  console.log(`主進(jìn)程 ${process.pid} 正在運行`);

  // 衍生工作進(jìn)程。
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  cluster.on('exit', (worker, code, signal) => {
    console.log(`工作進(jìn)程 ${worker.process.pid} 已退出`);
  });
} else {
  // 工作進(jìn)程可以共享任何 TCP 連接。
  // 在本例子中,共享的是 HTTP 服務(wù)器。
  http.createServer((req, res) => {
    res.writeHead(200);
    res.end('你好世界\n');
  }).listen(8000);

  console.log(`工作進(jìn)程 ${process.pid} 已啟動`);
}

cluster詳解

cluster模塊源自于lib/cluster.js,我們可以通過cluster.fork()來創(chuàng)建子工作進(jìn)程,用來處理主進(jìn)程的請求。

cluster中的event

cluster繼承自events.EventEmitter,所以cluster可以發(fā)送和接收event。

cluster支持7中event,分別是disconnect,exit,fork,listening,message,online和setup。

在講解disconnect之前,我們先介紹一個概念叫做IPC,IPC的全稱是Inter-Process Communication,也就是進(jìn)程間通信。

IPC主要用來進(jìn)行主進(jìn)程和子進(jìn)程之間的通信。一個工作進(jìn)程在創(chuàng)建后會自動連接到它的主進(jìn)程。 當(dāng) 'disconnect' 事件被觸發(fā)時才會斷開連接。

觸發(fā)disconnect事情的原因有很多,可以是主動調(diào)用worker.disconnect(),也可以是工作進(jìn)程退出或者被kill掉。

cluster.on('disconnect', (worker) => {
  console.log(`工作進(jìn)程 #${worker.id} 已斷開連接`);
});

exit事件會在任何一個工作進(jìn)程關(guān)閉的時候觸發(fā)。一般用來監(jiān)測cluster中某一個進(jìn)程是否異常退出,如果退出的話使用cluster.fork創(chuàng)建新的進(jìn)程,以保證有足夠多的進(jìn)程來處理請求。

cluster.on('exit', (worker, code, signal) => {
  console.log('工作進(jìn)程 %d 關(guān)閉 (%s). 重啟中...',
              worker.process.pid, signal || code);
  cluster.fork();
});

fork事件會在調(diào)用cluster.fork方法的時候被觸發(fā)。

const timeouts = [];
function errorMsg() {
  console.error('連接出錯');
}

cluster.on('fork', (worker) => {
  timeouts[worker.id] = setTimeout(errorMsg, 2000);
});

主進(jìn)程和工作進(jìn)程的listening事件都會在工作進(jìn)程調(diào)用listen方法的時候觸發(fā)。

cluster.on('listening', (worker, address) => {
  console.log(
    `工作進(jìn)程已連接到 ${address.address}:${address.port}`);
});

其中worker代表的是工作線程,而address中包含三個屬性:address、 port 和 addressType。 其中addressType有四個可選值:

  • 4 (TCPv4)
  • 6 (TCPv6)
  • -1 (Unix 域 socket)
  • 'udp4' or 'udp6' (UDP v4 或 v6)

message事件會在主進(jìn)程收到子進(jìn)程發(fā)送的消息時候觸發(fā)。

當(dāng)主進(jìn)程生成工作進(jìn)程時會觸發(fā)fork,當(dāng)工作進(jìn)程運行時會觸發(fā)online。

setupMaster方法被調(diào)用的時候,會觸發(fā)setup事件。

cluster中的方法

cluster中三個方法,分別是disconnect,fork和setupMaster。

cluster.disconnect([callback])

調(diào)用cluster的disconnect方法,實際上會在cluster中的每個worker中調(diào)用disconnect方法。從而斷開worker和主進(jìn)程的連接。

當(dāng)所有的worker都斷開連接之后,會執(zhí)行callback。

cluster.fork([env])

fork方法,會從主進(jìn)程中創(chuàng)建新的子進(jìn)程。其中env是要添加到進(jìn)程環(huán)境變量的鍵值對。

fork將會返回一個cluster.Worker對象,代表工作進(jìn)程。

最后一個方法是setupMaster:

cluster.setupMaster([settings])

默認(rèn)情況下,cluster通過fork方法來創(chuàng)建子進(jìn)程,但是我們可以通過setupMaster來改變這個行為。通過設(shè)置settings變量,我們可以改變后面fork子進(jìn)程的行為。

我們看一個setupMaster的例子:

const cluster = require('cluster');
cluster.setupMaster({
  exec: 'worker.js',
  args: ['--use', 'https'],
  silent: true
});
cluster.fork(); // https 工作進(jìn)程
cluster.setupMaster({
  exec: 'worker.js',
  args: ['--use', 'http']
});
cluster.fork(); // http 工作進(jìn)程

cluster中的屬性

通過cluster對象,我們可以通過isMaster和isWorker來判斷進(jìn)程是否主進(jìn)程。

可以通過worker來獲取當(dāng)前工作進(jìn)程對象的引用:

const cluster = require('cluster');

if (cluster.isMaster) {
  console.log('這是主進(jìn)程');
  cluster.fork();
  cluster.fork();
} else if (cluster.isWorker) {
  console.log(`這是工作進(jìn)程 #${cluster.worker.id}`);
}

可以通過workers來遍歷活躍的工作進(jìn)程對象:

// 遍歷所有工作進(jìn)程。
function eachWorker(callback) {
  for (const id in cluster.workers) {
    callback(cluster.workers[id]);
  }
}
eachWorker((worker) => {
  worker.send('通知所有工作進(jìn)程');
});

每個worker都有一個id編號,用來定位該worker。

cluster中的worker

worker類中包含了關(guān)于工作進(jìn)程的所有的公共的信息和方法。cluster.fork出來的就是worker對象。

worker的事件和cluster的很類似,支持6個事件:disconnect,error,exit,listening,message和online。

worker中包含3個屬性,分別是:id,process和exitedAfterDisconnect。

其中id是worker的唯一標(biāo)記。

worker中的process,實際上是ChildProcess對象,是通過child_process.fork()來創(chuàng)建出來的。

因為在worker中,process屬于全局變量,所以我們可以直接在worker中使用process來進(jìn)行發(fā)送消息。

exitedAfterDisconnect表示如果工作進(jìn)程由于 .kill() 或 .disconnect() 而退出的話,值就是true。如果是以其他方式退出的話,返回值就是false。如果工作進(jìn)程尚未退出,則為 undefined。

我們可以通過worker.exitedAfterDisconnect 來區(qū)分是主動退出還是被動退出,主進(jìn)程可以根據(jù)這個值決定是否重新生成工作進(jìn)程。

cluster.on('exit', (worker, code, signal) => {
  if (worker.exitedAfterDisconnect === true) {
    console.log('這是自發(fā)退出,無需擔(dān)心');
  }
});

// 殺死工作進(jìn)程。
worker.kill();

worker還支持6個方法,分別是:send,kill,destroy,disconnect,isConnected,isDead。

這里我們主要講解一下send方法來發(fā)送消息:

worker.send(message[, sendHandle[, options]][, callback])

可以看到send方法和child_process中的send方法參數(shù)其實是很類似的。而本質(zhì)上,worker.send在主進(jìn)程中,這會發(fā)送消息給特定的工作進(jìn)程。 相當(dāng)于 ChildProcess.send()。在工作進(jìn)程中,這會發(fā)送消息給主進(jìn)程。 相當(dāng)于 process.send()。

if (cluster.isMaster) {
  const worker = cluster.fork();
  worker.send('你好');

} else if (cluster.isWorker) {
  process.on('message', (msg) => {
    process.send(msg);
  });
}

在上面的例子中,如果是在主進(jìn)程中,那么可以使用worker.send來發(fā)送消息。而在子進(jìn)程中,則可以使用worker中的全局變量process來發(fā)送消息。

總結(jié)

使用cluster可以充分使用多核CPU的優(yōu)勢,希望大家在實際的項目中應(yīng)用起來。

以上就是淺談nodejs中創(chuàng)建cluster的詳細(xì)內(nèi)容,更多關(guān)于nodejs中創(chuàng)建cluster的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Mac中安裝nvm的教程分享

    Mac中安裝nvm的教程分享

    下面小編就為大家分享一篇Mac中安裝nvm的教程,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2017-12-12
  • 三種Node.js寫文件的方式

    三種Node.js寫文件的方式

    這篇文章主要為大家詳細(xì)介紹了三種Node.js寫文件的方式,感興趣的小伙伴們可以參考一下
    2016-03-03
  • Node.js全局可用變量、函數(shù)和對象示例詳解

    Node.js全局可用變量、函數(shù)和對象示例詳解

    JavaScript中有一個特殊的對象,稱為全局對象(Global Object),它及其所有屬性都可以在程序的任何地方訪問,即全局變量,下面這篇文章主要給大家介紹了關(guān)于Node.js全局可用變量、函數(shù)和對象的相關(guān)資料,需要的朋友可以參考下
    2023-03-03
  • nodeJs實現(xiàn)基于連接池連接mysql的方法示例

    nodeJs實現(xiàn)基于連接池連接mysql的方法示例

    這篇文章主要介紹了nodeJs實現(xiàn)基于連接池連接mysql的方法,結(jié)合具體實例形式分析了nodejs連接池操作mysql數(shù)據(jù)庫連接的實現(xiàn)與使用技巧,需要的朋友可以參考下
    2018-02-02
  • Node.js JSON模塊用法實例分析

    Node.js JSON模塊用法實例分析

    這篇文章主要介紹了Node.js JSON模塊用法,結(jié)合實例形式分析了node.js json模塊的基本語法,以及使用json模塊進(jìn)行json格式數(shù)據(jù)解析的相關(guān)操作技巧,需要的朋友可以參考下
    2019-01-01
  • Node.js進(jìn)程管理之子進(jìn)程詳解

    Node.js進(jìn)程管理之子進(jìn)程詳解

    本文詳細(xì)講解了Node.js進(jìn)程管理之子進(jìn)程,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-07-07
  • 一個簡單的node.js界面實現(xiàn)方法

    一個簡單的node.js界面實現(xiàn)方法

    今天小編就為大家分享一篇一個簡單的node.js界面實現(xiàn)方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-06-06
  • 用nodejs搭建websocket服務(wù)器

    用nodejs搭建websocket服務(wù)器

    這篇文章主要介紹了用nodejs搭建websocket服務(wù)器,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-01-01
  • 如何用nodejs給C#寫一個數(shù)據(jù)表的實體類生成工具

    如何用nodejs給C#寫一個數(shù)據(jù)表的實體類生成工具

    這篇文章主要介紹了如何用nodejs給C#寫一個數(shù)據(jù)表的實體類生成工具,對nodejs感興趣的同學(xué),可以參考下
    2021-05-05
  • Node.js利用斷言模塊assert進(jìn)行單元測試的方法

    Node.js利用斷言模塊assert進(jìn)行單元測試的方法

    最近在用Node寫一個實時聊天小應(yīng)用,其中就用到了單元測試,所以死下面這篇文章主要給大家介紹了關(guān)于Node.js利用斷言模塊assert進(jìn)行單元測試的方法,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-09-09

最新評論

双峰县| 金门县| 平乡县| 永安市| 洪湖市| 内乡县| 新源县| 紫阳县| 荔浦县| 岳池县| 静安区| 子长县| 泰和县| 安化县| 天津市| 虞城县| 卢龙县| 定远县| 云阳县| 武邑县| 洛阳市| 邵武市| 五寨县| 赤壁市| 根河市| 宁陵县| 天门市| 睢宁县| 汕尾市| 铜山县| 全椒县| 黔东| 双柏县| 安阳市| 香格里拉县| 丘北县| 陇西县| 成都市| 鲁甸县| 晋江市| 福鼎市|