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.mzph.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; 物价较高…