node【cluster】

文章详细介绍了Node.js中的cluster模块,包括主进程和工作进程的属性,如`isMaster`和`isWorker`,以及如何创建和管理工作进程。还讨论了`fork`、`disconnect`方法和`message`、`exit`等重要事件,用于进程间通信和异常处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


前言


cluster:Cluster

属性

cluster.isMaster:Boolean

返回一个布尔值,表示当前进程是否为主进程。这个属性由process.env.NODE_UNIQUE_ID决定,如果process.env.NODE_UNIQUE_ID为未定义,就表示该进程是主进程

const cluster=require('cluster');
cluster.isMaster

cluster.isWorker:Boolean

返回一个布尔值,与cluster.isMaster相反,表明进程是否是工作进程

cluster.isWorker

cluster.workers:Map< {id:Worker} >

返回一个,以id为key,worker进程对象为value的hash对象

const workers= cluster.workers;
for(id in workers){
	const worker=workers[id];
}

cluster.worker:Worker

返回一个当前工作进程的引用,主进程不可用

if(cluster.isWorker){
	console.log(`当前工作空间的引用${cluster.worker.id}`)
}

方法

cluster.fork():Worker

fork方法用于新建一个worker进程,上下文都复制主进程。只有主进程才能调用这个方法,在工作进程内调用此方法,会导致当前工作进程退出

cluster.fork();

cluster.disconnect(callback)

对所有worker进程调用disconnect方法,使得所有worker断开连接,接受一个callback回调函数,callback会在所有的worker断开连接后执行.

cluster.disconnect(()=>{
	console.log("所有连接断开后执行")
})

事件

cluster.on(‘message’)

worker进程调用send时触发

if(cluster.isMaster){
	cluster.on('message',(worker,data)=>{
		console.log(data); // {data:'data'}
	})
} else {
	process.send({data:'data'})
}

cluster.on(‘exit’)

worker进程死亡时,集群模块将触发 ‘exit’ 事件。可以通过fork创建一个新的worker

if(cluster.isMaster){
	cluster.on('exit',(worker)=>{
		console.log("exit",worker)
		cluster.fork(); // 当监听到一个worker kill后,再次派生一个worker,保持worker数量
	})
} else {
	cluster.worker.kill();
}

cluster.on(‘disconnect’)

当工作进程正常退出、被杀死、或手动断开连接(例如使用 worker.disconnect())时触发

if(cluster.isMaster){
	cluster.on('disconnect',(worker)=>{
		console.log("disconnect",worker)
		cluster.fork(); // 当监听到一个worker kill后,再次派生一个worker,保持worker数量
	})
} else {
	cluster.worker.kill();
	// 或者
	cluster.worker.disconnect();
}

cluster.on(‘fork’)

当worker进程被fork时触发

if(cluster.isMaster){
	cluster.on('fork',(worker)=>{
		console.log("exit",worker)
		cluster.fork(); // 当监听到一个worker kill后,再次派生一个worker,保持worker数量
	})
} 

worker:Worker

属性

worker.exitedAfterDisconnect

worker由于.kill() 或 .disconnect() 退出,则此属性为 true。 如果工作进程以任何其他方式退出,则为 false。可以通过值判断是否时自愿退出

cluster.on('exit', (worker, code, signal) => {
  if (worker.exitedAfterDisconnect === true) {
    console.log('Oh, it was just voluntary – no need to worry');
  }
});

// 杀死工作进程
worker.kill();

worker.id

worker进程的唯一id,一般用来从cluster.workers查找指定worker

cluster.workers[worker.id];

方法

worker.send()

与主进程进行通讯,触发cluster.message事件,send接受字符串或者json对象

worker.send({
	type:"
})

worker.send('msg')

worker.disconnect()

终端与主进程的连接,触发cluster.disconnect事件

worker.disconnect();

worker.kill()

杀死worker进程,将会触发cluster.disconnect事件、cluster.exit事件

worker.kill()

事件

disconnect

调用kill()和disconnect(),都会触发此事件,只在本工作进程中生效

if(cluster.isMaster){
	const worker=cluster.fork();
	worker.on("message",(data)=>{
		console.log("data====",data); // index
	})
}

// worker
process.send("index")
message

监听worker进程数据通讯,只能在主进程中使用,与cluster.on(“message”)不同的是,它只会监听特定的worker

if(cluster.isMaster){
	const worker=cluster.fork();
	worker.on("message",(data)=>{
		console.log("data====",data); // index
	})
}

// worker
process.send("index")
exit

worker调用kill()触发

if(cluster.isMaster){
	const worker=cluster.fork();
	worker.on("message",(data)=>{
		console.log("data====",data); // index
	})
}

// worker
process.send("index")
error

子应用中出现未捕获的异常时触发

if(cluster.isMaster){
	const worker=cluster.fork();
	worker.on("error",(data)=>{
		console.log("error====",data); // index
	})
}

// worker
throw Error("error")
### 使用 Node.js Cluster 模块进行多线程编程 Node.js 是基于单线程事件循环架构,这使得它非常适合处理I/O密集型应用。然而,在CPU密集型任务或多核处理器环境中,这种模式可能会限制性能。为了克服这一局限并充分利用硬件资源,可以采用内置的`cluster`模块创建子进程[^1]。 #### 创建主工作器(Master Worker) 当启动一个Node.js程序时,默认情况下只有一个主线程运行。通过引入`cluster.fork()`方法可以在同一台机器上复制多个实例即工作者(worker),从而形成所谓的“集群”。每个新产生的worker都会拥有独立的工作空间以及文件描述符副本。 ```javascript const cluster = require('cluster'); const http = require('http'); const numCPUs = require('os').cpus().length; if (cluster.isPrimary) { console.log(`主进程 ${process.pid} 正在运行`); // 叉出 worker. for (let i = 0; i < numCPUs; i++) { cluster.fork(); } cluster.on('exit', (worker, code, signal) => { console.log(`worker ${worker.process.pid} 已退出`); }); } else { // Workers can share any TCP connection // In this case it is an HTTP server const server = http.createServer((req, res) => { res.writeHead(200); res.end('hello world\n'); }); server.listen(8000); console.log(`Worker ${process.pid} 开始`); } ``` 这段脚本展示了如何设置一个多进程的应用程序结构。如果当前环境为主进程,则会根据可用的核心数量生成相应数目的子进程;反之则作为普通的HTTP服务器监听指定端口等待请求到来。 #### 处理消息传递机制 除了简单的分发网络连接外,还可以利用`cluster`提供的通信接口让不同节点之间交换信息。比如向特定work发送指令或者收集它们的状态报告等操作都可以借助于`.send()`和对应的监听回调完成。 ```javascript // 主进程中给某个具体的worker传信 someWorker.send({ hello: 'world' }); // 子进程中接收来自父级的消息 process.on('message', function(msg){ console.dir(msg); }); ``` 以上就是关于怎样运用 `cluster` 来增强 Node.js 应用并发能力的方法概述。值得注意的是虽然这种方法确实有助于提升某些类型的负载表现,但在实际部署之前还需要考虑诸如内存占用、调试难度等因素的影响。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

极简风格

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值