网易首页 > 网易号 > 正文 申请入驻

在nodejs中创建cluster

0
分享至

简介

在前面的文章中,我们讲到了可以通过worker_threads来创建新的线程,可以使用child_process来创建新的子进程。本文将会介绍如何创建nodejs的集群cluster。

cluster集群

我们知道,nodejs的event loop或者说事件响应处理器是单线程的,但是现在的CPU基本上都是多核的,为了充分利用现代CPU多核的特性,我们可以创建cluster,从而使多个子进程来共享同一个服务器端口。

也就是说,通过cluster,我们可以使用多个子进程来服务处理同一个端口的请求。

先看一个简单的http server中使用cluster的例子:

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

if (cluster.isMaster) {
console.log(`主进程 {process.pid} 正在运行`);

// 衍生工作进程。
for (let i = 0; i{worker.process.pid} 已退出`);
});
} else {
// 工作进程可以共享任何 TCP 连接。
// 在本例子中,共享的是 HTTP 服务器。
http.createServer((req, res) => {
res.writeHead(200);
res.end('你好世界\n');
}).listen(8000);

console.log(`工作进程 ${process.pid} 已启动`);
}

cluster详解

cluster模块源自于lib/cluster.js,我们可以通过cluster.fork()来创建子工作进程,用来处理主进程的请求。

cluster中的event

cluster继承自events.EventEmitter,所以cluster可以发送和接收event。

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

在讲解disconnect之前,我们先介绍一个概念叫做IPC,IPC的全称是Inter-Process Communication,也就是进程间通信。

IPC主要用来进行主进程和子进程之间的通信。一个工作进程在创建后会自动连接到它的主进程。当 ‘disconnect’ 事件被触发时才会断开连接。

触发disconnect事情的原因有很多,可以是主动调用worker.disconnect(),也可以是工作进程退出或者被kill掉。

cluster.on('disconnect', (worker) => {
console.log(`工作进程 #${worker.id} 已断开连接`);

exit事件会在任何一个工作进程关闭的时候触发。一般用来监测cluster中某一个进程是否异常退出,如果退出的话使用cluster.fork创建新的进程,以保证有足够多的进程来处理请求。

cluster.on('exit', (worker, code, signal) => {
console.log('工作进程 %d 关闭 (%s). 重启中...',
worker.process.pid, signal || code);
cluster.fork();

fork事件会在调用cluster.fork方法的时候被触发。

const timeouts = [];
function errorMsg() {
console.error('连接出错');

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

主进程和工作进程的listening事件都会在工作进程调用listen方法的时候触发。

cluster.on('listening', (worker, address) => {
console.log(
`工作进程已连接到 {address.address}:{address.port}`);

其中worker代表的是工作线程,而address中包含三个属性:address、 port 和 addressType。其中addressType有四个可选值:

  • 4 (TCPv4)

  • 6 (TCPv6)

  • -1 (Unix 域 socket)

  • ‘udp4’ or ‘udp6’ (UDP v4 或 v6)

message事件会在主进程收到子进程发送的消息时候触发。

当主进程生成工作进程时会触发fork,当工作进程运行时会触发online。

setupMaster方法被调用的时候,会触发setup事件。

cluster中的方法

cluster中三个方法,分别是disconnect,fork和setupMaster。

cluster.disconnect([callback])

调用cluster的disconnect方法,实际上会在cluster中的每个worker中调用disconnect方法。从而断开worker和主进程的连接。

当所有的worker都断开连接之后,会执行callback。

cluster.fork([env])

fork方法,会从主进程中创建新的子进程。其中env是要添加到进程环境变量的键值对。

fork将会返回一个cluster.Worker对象,代表工作进程。

最后一个方法是setupMaster:

cluster.setupMaster([settings])

默认情况下,cluster通过fork方法来创建子进程,但是我们可以通过setupMaster来改变这个行为。通过设置settings变量,我们可以改变后面fork子进程的行为。

我们看一个setupMaster的例子:

const cluster = require('cluster');
cluster.setupMaster({
exec: 'worker.js',
args: ['--use', 'https'],
silent: true
cluster.fork(); // https 工作进程
cluster.setupMaster({
exec: 'worker.js',
args: ['--use', 'http']
cluster.fork(); // http 工作进程
cluster中的属性

通过cluster对象,我们可以通过isMaster和isWorker来判断进程是否主进程。

可以通过worker来获取当前工作进程对象的引用:

const cluster = require('cluster');

if (cluster.isMaster) {
console.log('这是主进程');
cluster.fork();
cluster.fork();
} else if (cluster.isWorker) {
console.log(`这是工作进程 #${cluster.worker.id}`);
}

可以通过workers来遍历活跃的工作进程对象:

// 遍历所有工作进程。
function eachWorker(callback) {
for (const id in cluster.workers) {
callback(cluster.workers[id]);

eachWorker((worker) => {
worker.send('通知所有工作进程');

每个worker都有一个id编号,用来定位该worker。

cluster中的worker

worker类中包含了关于工作进程的所有的公共的信息和方法。cluster.fork出来的就是worker对象。

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

worker中包含3个属性,分别是:id,process和exitedAfterDisconnect。

其中id是worker的唯一标记。

worker中的process,实际上是ChildProcess对象,是通过child_process.fork()来创建出来的。

因为在worker中,process属于全局变量,所以我们可以直接在worker中使用process来进行发送消息。

exitedAfterDisconnect表示如果工作进程由于 .kill() 或 .disconnect() 而退出的话,值就是true。如果是以其他方式退出的话,返回值就是false。如果工作进程尚未退出,则为 undefined。

我们可以通过worker.exitedAfterDisconnect 来区分是主动退出还是被动退出,主进程可以根据这个值决定是否重新生成工作进程。

cluster.on('exit', (worker, code, signal) => {
if (worker.exitedAfterDisconnect === true) {
console.log('这是自发退出,无需担心');

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

worker还支持6个方法,分别是:send,kill,destroy,disconnect,isConnected,isDead。

这里我们主要讲解一下send方法来发送消息:

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

可以看到send方法和child_process中的send方法参数其实是很类似的。而本质上,worker.send在主进程中,这会发送消息给特定的工作进程。相当于 ChildProcess.send()。在工作进程中,这会发送消息给主进程。相当于 process.send()。

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

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

在上面的例子中,如果是在主进程中,那么可以使用worker.send来发送消息。而在子进程中,则可以使用worker中的全局变量process来发送消息。

总结

使用cluster可以充分使用多核CPU的优势,希望大家在实际的项目中应用起来。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
英国葛兰素史克(GSK)股价上涨63.7%

英国葛兰素史克(GSK)股价上涨63.7%

每日经济新闻
2026-01-20 22:41:16
山东女子曝老公出轨小姑子,在父母屋里抓现行:评论区沸腾!

山东女子曝老公出轨小姑子,在父母屋里抓现行:评论区沸腾!

农村情感故事
2026-01-17 18:47:28
64年斯诺访华,和周恩来谈话提及无锡,周恩来警觉:去看了工厂?

64年斯诺访华,和周恩来谈话提及无锡,周恩来警觉:去看了工厂?

大运河时空
2026-01-20 08:20:03
传说曾是刑场?深圳这栋“蜡烛楼”,看一眼后背发凉!

传说曾是刑场?深圳这栋“蜡烛楼”,看一眼后背发凉!

GA环球建筑
2026-01-20 18:36:15
越媒:越南后卫严重受伤,其父母不忍观看提前离开观战现场

越媒:越南后卫严重受伤,其父母不忍观看提前离开观战现场

野渡舟山人
2026-01-21 09:02:02
国家发改委:进一步清理消费领域不合理的限制措施 加快培育消费新的增长点

国家发改委:进一步清理消费领域不合理的限制措施 加快培育消费新的增长点

财联社
2026-01-20 10:47:13
贾玲巴黎周“一脸男相”!不爱笑也没梨涡眼神犀利,梳大背头好酷

贾玲巴黎周“一脸男相”!不爱笑也没梨涡眼神犀利,梳大背头好酷

轩逸阿II
2026-01-20 07:54:29
一万人中,能有多少人晚年还能健全走路?少坐多站的人,告诉实话

一万人中,能有多少人晚年还能健全走路?少坐多站的人,告诉实话

健康科普365
2026-01-18 16:35:03
“陈真”梁小龙去世,77岁的“霍元甲”黄元申如今咋样了?

“陈真”梁小龙去世,77岁的“霍元甲”黄元申如今咋样了?

叨唠
2026-01-20 20:49:59
“嫣然天使儿童医院”患儿家属:很震惊

“嫣然天使儿童医院”患儿家属:很震惊

中国新闻周刊
2026-01-20 21:29:47
难以置信!网传东莞一女子哭诉,俩大男人蹲家啃她,直言要崩溃了

难以置信!网传东莞一女子哭诉,俩大男人蹲家啃她,直言要崩溃了

火山诗话
2026-01-20 07:40:49
社会运行逻辑:穷人不生孩子,富人的阶层就会倒退

社会运行逻辑:穷人不生孩子,富人的阶层就会倒退

舒山有鹿
2026-01-19 09:02:09
路由器背面的USB接口别闲置!5个强大用法,不用真的亏大了

路由器背面的USB接口别闲置!5个强大用法,不用真的亏大了

小柱解说游戏
2026-01-20 09:37:30
鸿蒙智行回应“尊界S800起火”:非车辆原因

鸿蒙智行回应“尊界S800起火”:非车辆原因

观察者网
2026-01-20 12:32:04
与西贝刚好相反,萨莉亚生怕你不知道它用预制菜

与西贝刚好相反,萨莉亚生怕你不知道它用预制菜

狐狸先森讲升学规划
2026-01-20 13:41:33
中央定调!退休新规实施,公务员以及事业编制,不能延迟退休吗?

中央定调!退休新规实施,公务员以及事业编制,不能延迟退休吗?

另子维爱读史
2026-01-20 19:44:51
中方话音刚落,特朗普通告全世界:税率加到200%!首个牺牲国出现

中方话音刚落,特朗普通告全世界:税率加到200%!首个牺牲国出现

阿离家居
2026-01-21 08:25:57
官二代高速上殴打宝马车主,一小时后被十几辆装甲车包围

官二代高速上殴打宝马车主,一小时后被十几辆装甲车包围

历史八卦社
2024-09-14 16:48:46
游客吐槽西岭雪山景区“吃相太难看”,花240元买门票上山后雪地却被围起来单独收费!发布者:景区官方称会抓紧时间整改

游客吐槽西岭雪山景区“吃相太难看”,花240元买门票上山后雪地却被围起来单独收费!发布者:景区官方称会抓紧时间整改

洪观新闻
2026-01-20 15:46:24
冯德莱恩:欧盟决定永久冻结 俄罗斯资产并保留使用权利

冯德莱恩:欧盟决定永久冻结 俄罗斯资产并保留使用权利

每日经济新闻
2026-01-20 19:23:41
2026-01-21 09:40:49
flydean程序那些事
flydean程序那些事
最通俗的解读,最深刻的干货!
356文章数 438关注度
往期回顾 全部

科技要闻

中芯国际等巨头集体提价,8英寸芯片最高涨20%

头条要闻

外交部副部长孙卫东:中方绝不允许家门口生战、生乱

头条要闻

外交部副部长孙卫东:中方绝不允许家门口生战、生乱

体育要闻

如果NBA只剩下最后一个传统中锋

娱乐要闻

网红版闫学晶!600万粉博主阿爆翻车

财经要闻

拆解涉税黑中介虚开套路

汽车要闻

奇瑞张贵兵:墨甲不做秀技术的企业 只做痛点终结者

态度原创

数码
房产
游戏
旅游
公开课

数码要闻

功能夸大、操作复杂,央视曝光部分“伪智能”家居

房产要闻

中旅・三亚蓝湾发布会揭秘自贸港好房子高阶形态

在《星际争霸Ⅱ》国际明星邀请赛现场,大家都是当初那个少年"/> 主站 商城 论坛 自运营 登录 注册 在《星际争霸Ⅱ》国际明星邀请赛现场,大家都是当初那...

旅游要闻

福建厦门:布置彩灯迎新春

公开课

李玫瑾:为什么性格比能力更重要?

无障碍浏览 进入关怀版