Node.js種cluster模塊詳解

Node.js 中 cluster 模塊全部 API 詳解

1. 模塊屬性

const cluster = require('cluster');// 1. isMaster
// 判斷當前進程是否為主進程
console.log('是否為主進程:', cluster.isMaster);// 2. isWorker
// 判斷當前進程是否為工作進程
console.log('是否為工作進程:', cluster.isWorker);// 3. schedulingPolicy
// 獲取或設置調度策略
// SCHED_NONE: 由操作系統調度
// SCHED_RR: 輪詢調度
console.log('當前調度策略:', cluster.schedulingPolicy);
cluster.schedulingPolicy = cluster.SCHED_RR;// 4. workers
// 獲取所有工作進程的引用
console.log('工作進程數量:', Object.keys(cluster.workers).length);

2. 主進程方法

// 1. fork()
// 創建新的工作進程
const worker = cluster.fork();// 2. setupMaster([settings])
// 配置主進程
cluster.setupMaster({exec: 'worker.js',      // 工作進程文件args: ['--use', 'http'], // 傳遞給工作進程的參數silent: false,          // 是否將工作進程的輸出重定向到主進程stdio: ['pipe', 'pipe', 'pipe', 'ipc'], // 標準輸入輸出配置uid: 1000,             // 用戶 IDgid: 1000,             // 組 IDinspectPort: 0         // 調試端口
});// 3. disconnect([callback])
// 斷開所有工作進程的連接
cluster.disconnect(() => {console.log('所有工作進程已斷開連接');
});// 4. settings
// 獲取當前配置
console.log('當前配置:', cluster.settings);

3. 工作進程屬性

// 1. worker.id
// 獲取工作進程 ID
console.log('工作進程 ID:', cluster.worker.id);// 2. worker.process
// 獲取工作進程的進程對象
console.log('進程 ID:', cluster.worker.process.pid);// 3. worker.exitedAfterDisconnect
// 判斷工作進程是否在斷開連接后退出
console.log('是否在斷開連接后退出:', cluster.worker.exitedAfterDisconnect);// 4. worker.isDead()
// 判斷工作進程是否已死亡
console.log('是否已死亡:', cluster.worker.isDead());// 5. worker.isConnected()
// 判斷工作進程是否已連接
console.log('是否已連接:', cluster.worker.isConnected());

4. 工作進程方法

// 1. worker.send(message[, sendHandle][, callback])
// 發送消息給主進程
cluster.worker.send('hello from worker', (err) => {if (err) console.error('發送消息失敗:', err);
});// 2. worker.disconnect()
// 斷開工作進程連接
cluster.worker.disconnect();// 3. worker.kill([signal])
// 終止工作進程
cluster.worker.kill('SIGTERM');

5. 事件

5.1 主進程事件

// 1. fork
// 當創建新的工作進程時觸發
cluster.on('fork', (worker) => {console.log('工作進程已創建:', worker.id);
});// 2. online
// 當工作進程上線時觸發
cluster.on('online', (worker) => {console.log('工作進程已上線:', worker.id);
});// 3. listening
// 當工作進程開始監聽時觸發
cluster.on('listening', (worker, address) => {console.log('工作進程正在監聽:', worker.id, address);
});// 4. message
// 當收到工作進程消息時觸發
cluster.on('message', (worker, message, handle) => {console.log('收到工作進程消息:', worker.id, message);
});// 5. disconnect
// 當工作進程斷開連接時觸發
cluster.on('disconnect', (worker) => {console.log('工作進程已斷開連接:', worker.id);
});// 6. exit
// 當工作進程退出時觸發
cluster.on('exit', (worker, code, signal) => {console.log('工作進程已退出:', worker.id, code, signal);
});// 7. error
// 當工作進程發生錯誤時觸發
cluster.on('error', (worker, code, signal) => {console.log('工作進程錯誤:', worker.id, code, signal);
});

5.2 工作進程事件

// 1. message
// 當收到主進程消息時觸發
cluster.worker.on('message', (message, handle) => {console.log('收到主進程消息:', message);
});// 2. disconnect
// 當工作進程斷開連接時觸發
cluster.worker.on('disconnect', () => {console.log('工作進程已斷開連接');
});// 3. error
// 當工作進程發生錯誤時觸發
cluster.worker.on('error', (code, signal) => {console.log('工作進程錯誤:', code, signal);
});// 4. exit
// 當工作進程退出時觸發
cluster.worker.on('exit', (code, signal) => {console.log('工作進程已退出:', code, signal);
});

6. 完整示例

const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;if (cluster.isMaster) {console.log(`主進程 ${process.pid} 正在運行`);// 配置主進程cluster.setupMaster({exec: 'worker.js',args: ['--use', 'http'],silent: false});// 啟動工作進程for (let i = 0; i < numCPUs; i++) {cluster.fork();}// 主進程事件處理cluster.on('fork', (worker) => {console.log('工作進程已創建:', worker.id);});cluster.on('online', (worker) => {console.log('工作進程已上線:', worker.id);});cluster.on('listening', (worker, address) => {console.log('工作進程正在監聽:', worker.id, address);});cluster.on('message', (worker, message, handle) => {console.log('收到工作進程消息:', worker.id, message);worker.send('消息已收到');});cluster.on('disconnect', (worker) => {console.log('工作進程已斷開連接:', worker.id);});cluster.on('exit', (worker, code, signal) => {console.log('工作進程已退出:', worker.id, code, signal);// 重啟工作進程cluster.fork();});cluster.on('error', (worker, code, signal) => {console.log('工作進程錯誤:', worker.id, code, signal);});// 定期檢查工作進程狀態setInterval(() => {for (const id in cluster.workers) {const worker = cluster.workers[id];console.log(`工作進程 ${worker.id} 狀態:`, {pid: worker.process.pid,isDead: worker.isDead(),isConnected: worker.isConnected(),exitedAfterDisconnect: worker.exitedAfterDisconnect});}}, 5000);// 優雅關閉process.on('SIGTERM', () => {console.log('收到 SIGTERM 信號,開始優雅關閉');for (const id in cluster.workers) {cluster.workers[id].send('shutdown');cluster.workers[id].disconnect();}});
} else {// 工作進程代碼const server = http.createServer((req, res) => {res.writeHead(200);res.end(`你好世界,來自工作進程 ${process.pid}\n`);});server.listen(8000);// 工作進程事件處理cluster.worker.on('message', (message) => {console.log('收到主進程消息:', message);if (message === 'shutdown') {server.close(() => {console.log(`工作進程 ${process.pid} 已關閉`);process.exit(0);});}});cluster.worker.on('disconnect', () => {console.log('工作進程已斷開連接');});cluster.worker.on('error', (code, signal) => {console.log('工作進程錯誤:', code, signal);});cluster.worker.on('exit', (code, signal) => {console.log('工作進程已退出:', code, signal);});// 定期發送心跳setInterval(() => {cluster.worker.send('heartbeat');}, 30000);
}

7. 高級用法

// 1. 動態調整工作進程數量
const cluster = require('cluster');
const http = require('http');
const os = require('os');if (cluster.isMaster) {let workerCount = os.cpus().length;console.log(`初始工作進程數量: ${workerCount}`);// 啟動工作進程for (let i = 0; i < workerCount; i++) {cluster.fork();}// 動態調整工作進程數量process.on('SIGUSR1', () => {workerCount = Math.max(1, workerCount - 1);console.log(`減少工作進程數量至: ${workerCount}`);const workers = Object.values(cluster.workers);if (workers.length > workerCount) {workers[workers.length - 1].disconnect();}});process.on('SIGUSR2', () => {workerCount = Math.min(os.cpus().length * 2, workerCount + 1);console.log(`增加工作進程數量至: ${workerCount}`);if (Object.keys(cluster.workers).length < workerCount) {cluster.fork();}});
}// 2. 工作進程負載均衡
const cluster = require('cluster');
const http = require('http');
const os = require('os');if (cluster.isMaster) {const workerCount = os.cpus().length;const workers = [];// 啟動工作進程for (let i = 0; i < workerCount; i++) {const worker = cluster.fork();workers.push({worker,load: 0,connections: 0});}// 負載均衡http.createServer((req, res) => {// 選擇負載最低的工作進程const target = workers.reduce((min, w) => w.load < min.load ? w : min, workers[0]);target.connections++;target.load = target.connections / 100; // 簡單的負載計算// 轉發請求target.worker.send('request', { url: req.url });}).listen(8000);// 處理工作進程響應cluster.on('message', (worker, message) => {if (message.type === 'response') {const workerInfo = workers.find(w => w.worker.id === worker.id);if (workerInfo) {workerInfo.connections--;workerInfo.load = workerInfo.connections / 100;}}});
}// 3. 工作進程健康檢查
const cluster = require('cluster');
const http = require('http');if (cluster.isMaster) {const workers = new Map();// 啟動工作進程for (let i = 0; i < 4; i++) {const worker = cluster.fork();workers.set(worker.id, {worker,healthy: true,lastHeartbeat: Date.now()});}// 健康檢查setInterval(() => {const now = Date.now();for (const [id, info] of workers) {if (now - info.lastHeartbeat > 30000) {console.log(`工作進程 ${id} 可能已死亡`);info.healthy = false;info.worker.kill();const newWorker = cluster.fork();workers.set(newWorker.id, {worker: newWorker,healthy: true,lastHeartbeat: now});}}}, 5000);// 處理心跳cluster.on('message', (worker, message) => {if (message === 'heartbeat') {const info = workers.get(worker.id);if (info) {info.healthy = true;info.lastHeartbeat = Date.now();}}});
}

cluster 模塊的主要特點:

  1. 支持多核 CPU 并行處理
  2. 提供完整的事件系統
  3. 支持進程間通信
  4. 支持動態調整工作進程數量
  5. 支持負載均衡和健康檢查

使用建議:

  1. 根據 CPU 核心數合理設置工作進程數量
  2. 實現完善的錯誤處理和重啟機制
  3. 使用事件系統進行進程間通信
  4. 實現健康檢查確保系統穩定性
  5. 考慮使用更高級的進程管理工具(如 PM2)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/75508.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/75508.shtml
英文地址,請注明出處:http://en.pswp.cn/web/75508.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

融合動態權重與抗刷機制的網文評分系統——基于優書網、IMDB與Reddit的混合算法實踐

? Yumuing 博客 &#x1f680; 探索技術的每一個角落&#xff0c;解碼世界的每一種可能&#xff01; &#x1f48c; 如果你對 AI 充滿好奇&#xff0c;歡迎關注博主&#xff0c;訂閱專欄&#xff0c;讓我們一起開啟這段奇妙的旅程&#xff01; 以權威用戶為核心&#xff0c;時…

使用Golang打包jar應用

文章目錄 背景Go 的 go:embed 功能介紹與打包 JAR 文件示例1. go:embed 基礎介紹基本特性基本語法 2. 嵌入 JAR 文件示例項目結構代碼實現 3. 高級用法&#xff1a;嵌入多個文件或目錄4. 使用注意事項5. 實際應用場景6. 完整示例&#xff1a;運行嵌入的JAR 背景 想把自己的一個…

前端大屏可視化項目 局部全屏(指定盒子全屏)

需求是這樣的&#xff0c;我用的項目是vue admin 項目 現在需要在做大屏項目 不希望顯示除了大屏的其他東西 于是想了這個辦法 至于大屏適配問題 請看我文章 底部的代碼直接復制就可以運行 vue2 px轉rem 大屏適配方案 postcss-pxtorem-CSDN博客 <template><div …

《2025藍橋杯C++B組:D:產值調整》

**作者的個人gitee**?? 作者的算法講解主頁?? 每日一言&#xff1a;“淚眼問花花不語&#xff0c;亂紅飛過秋千去&#x1f338;&#x1f338;” 題目 二.解題策略 本題比較簡單&#xff0c;我的思路是寫三個函數分別計算黃金白銀銅一次新產值&#xff0c;通過k次循環即可獲…

[VTK] 四元素實現旋轉平移

VTK 實現旋轉&#xff0c;有四元數的方案&#xff0c;也有 vtkTransform 的方案&#xff1b;主要示例代碼如下&#xff1a; //構造旋轉四元數vtkQuaterniond rotation;rotation.SetRotationAngleAndAxis(vtkMath::RadiansFromDegrees(90.0),0.0, 1.0, 0.0);//構造旋轉點四元數v…

華為hcie證書的有效期怎么判斷?

在ICT行業&#xff0c;華為HCIE證書堪稱含金量極高的“敲門磚”&#xff0c;擁有它往往意味著在職場上更上一層樓。然而&#xff0c;很多人在辛苦考取HCIE證書后&#xff0c;卻對其有效期相關事宜一知半解。今天&#xff0c;咱們就來好好嘮嘮華為HCIE證書的有效期怎么判斷這個關…

【精品PPT】2025固態電池知識體系及最佳實踐PPT合集(36份).zip

精品推薦&#xff0c;2025固態電池知識體系及最佳實踐PPT合集&#xff0c;共36份。供大家學習參考。 1、中科院化學所郭玉國研究員&#xff1a;固態金屬鋰電池及其關鍵材料.pdf 2、中科院物理所-李泓固態電池.pdf 3、全固態電池技術研究進展.pdf 4、全固態電池生產工藝.pdf 5、…

MySQL 中為產品添加靈活的自定義屬性(如 color/size)

方案 1&#xff1a;EAV 模型&#xff08;最靈活但較復雜&#xff09; 適合需要無限擴展自定義屬性的場景 -- 產品表 CREATE TABLE products (id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(100),price DECIMAL(10,2) );-- 屬性名表 CREATE TABLE attributes (id INT PRIMA…

CSPM認證對項目論證的范式革新:從合規審查到價值創造的戰略躍遷

引言 在數字化轉型浪潮中&#xff0c;全球企業每年因項目論證缺陷導致的損失高達1.7萬億美元&#xff08;Gartner 2023&#xff09;。CSPM&#xff08;Certified Strategic Project Manager&#xff09;認證體系通過結構化方法論&#xff0c;將傳統的項目可行性評估升級為戰略…

CLIP中的Zero-Shot Learning原理

CLIP&#xff08;Contrastive Language-Image Pretraining&#xff09;是一種由OpenAI提出的多模態模型&#xff0c;它通過對比學習的方式同時學習圖像和文本的表示&#xff0c;并且能在多種任務中進行零樣本學習&#xff08;Zero-Shot Learning&#xff09;。CLIP模型的核心創…

spring mvc 中 RestTemplate 全面詳解及示例

RestTemplate 全面詳解及示例 1. RestTemplate 簡介 定義&#xff1a;Spring 提供的同步 HTTP 客戶端&#xff0c;支持多種 HTTP 方法&#xff08;GET/POST/PUT/DELETE 等&#xff09;&#xff0c;用于調用 RESTful API。核心特性&#xff1a; 支持請求頭、請求體、URI 參數的…

北大:LLM在NL2SQL中任務分解

&#x1f4d6;標題&#xff1a;LearNAT: Learning NL2SQL with AST-guided Task Decomposition for Large Language Models &#x1f310;來源&#xff1a;arXiv, 2504.02327 &#x1f31f;摘要 &#x1f538;自然語言到SQL&#xff08;NL2SQL&#xff09;已成為實現與數據庫…

STM32LL庫編程系列第八講——ADC模數轉換

系列文章目錄 往期文章 STM32LL庫編程系列第一講——Delay精準延時函數&#xff08;詳細&#xff0c;適合新手&#xff09; STM32LL庫編程系列第二講——藍牙USART串口通信&#xff08;步驟詳細、原理清晰&#xff09; STM32LL庫編程系列第三講——USARTDMA通信 STM32LL庫編程…

網絡5 TCP/IP 虛擬機橋接模式、NAT、僅主機模式

TCP/IP模型 用于局域網和廣域網&#xff1b;多個協議&#xff1b;每一層呼叫下一層&#xff1b;四層&#xff1b;通用標準 TCP/IP模型 OSI七層模型 應用層 應用層 表示層 會話層 傳輸層 傳輸層 網絡層 網絡層 鏈路層 數據鏈路層 物理層 鏈路層&#xff1a;傳數據幀&#xff0…

【C語言】預處理(下)(C語言完結篇)

一、#和## 1、#運算符 這里的#是一個運算符&#xff0c;整個運算符會將宏的參數轉換為字符串字面量&#xff0c;它僅可以出現在帶參數的宏的替換列表中&#xff0c;我們可以將其理解為字符串化。 我們先看下面的一段代碼&#xff1a; 第二個printf中是由兩個字符串組成的&am…

【高性能緩存Redis_中間件】一、快速上手redis緩存中間件

一、鋪墊 在當今的軟件開發領域&#xff0c;消息隊列扮演著至關重要的角色。它能夠幫助我們實現系統的異步處理、流量削峰以及系統解耦等功能&#xff0c;從而提升系統的性能和可維護性。Redis 作為一款高性能的鍵值對數據庫&#xff0c;不僅提供了豐富的數據結構&#xff0c;…

Java如何獲取文件的編碼格式?

Java獲取文件的編碼格式 在計算機中&#xff0c;文件編碼是指將文件內容轉換成二進制形式以便存儲和傳輸的過程。常見的文件編碼格式包括UTF-8、GBK等。不同的編碼使用不同的字符集和字節序列&#xff0c;因此在讀取文件時需要正確地確定文件的編碼格式 Java提供了多種方式以獲…

客戶端負載均衡與服務器端負載均衡詳解

客戶端負載均衡與服務器端負載均衡詳解 1. 客戶端負載均衡&#xff08;Client-Side Load Balancing&#xff09; 核心概念 定義&#xff1a;負載均衡邏輯在客戶端實現&#xff0c;客戶端主動選擇目標服務實例。典型場景&#xff1a;微服務內部調用&#xff08;如Spring Cloud…

Quartus II的IP核調用及仿真測試

目錄 第一章 什么是IP核&#xff1f;第二章 什么是LPM&#xff1f;第一節 設置LPM_COUNTER模塊參數第二節 仿真 第三章 什么是PLL&#xff1f;第一節 設置ALTPLL&#xff08;嵌入式鎖相環&#xff09;模塊參數第二節 仿真 第四章 什么是RAM&#xff1f;第一節 RAM_1PORT的調用第…

各地物價和生活成本 東歐篇

東歐地區的物價差異相對較大&#xff0c;一些國家的物價較高&#xff0c;而另一些國家則相對便宜。這些差異主要受當地經濟發展水平、工資水平、旅游業發展以及國際關系等因素影響。以下是一些典型的東歐國家&#xff0c;按物價高低進行分類&#xff1a; &#x1f30d; 物價較高…