Node学习记录: cluster模块

拓朴薄雾
• 阅读 2535

在如今机器的CPU都是多核的背景下,Node的单线程设计已经没法更充分的"压榨"机器性能了。所以从v0.8开始,Node新增了一个内置模块——“cluster”,故名思议,它可以通过一个父进程管理一坨子进程的方式来实现集群的功能。

cluster 的功能是生成与当前进程相同的子进程,并且允许父进程和子进程之间共享端口。
Node.js 的另一个核心模块child_process 也提供了相似的进程生成功能,但最大的区别在于 cluster 允许跨进程端
口复用,给我们的网络服务器开发带来了很大的方便 。

var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length; // 获取CPU的个数
 
if (cluster.isMaster) {
    for (var i = 0; i < numCPUs; i++) {
        cluster.fork();
    }
 
    cluster.on('exit', function(worker, code, signal) {
        console.log('worker ' + worker.process.pid + ' died');
    });
} else {
    http.createServer(function(req, res) {
        res.writeHead(200);
        res.end("hello world\n");
    }).listen(8000);
}

通过isMaster属性,判断是否Master进程,是则fork子进程,否则启动一个server。每个HTTP server都能监听到同一个端口。
但是在实际项目中,我们的启动代码一般都已经封装在了app.js中,要把整块启动逻辑嵌在上面的if else中实在不优雅。 所以,我们可以这样:

var cluster = require('cluster');
var numCPUs = require('os').cpus().length;
 
if (cluster.isMaster) {
    for (var i = 0; i < numCPUs; i++) {
        cluster.fork();
    }
    // 其它代码
    
} else {
    require("./app.js");
}

简单之处就在于原本的应用逻辑根本不需要知道自己是在集群还是单边。(当然,如果应用在内存中维护了某些状态,比如session,就需要运用某些机制来共享了,这里不详说)

而 Node.js 官方 Cluster 模块中包含一段简介:

单个 Node.js 实例在单线程环境下运行。为了更好地利用多核环境,用户有时希望启动一批 Node.js 进程用于加载。
集群化模块使得你很方便地创建子进程,以便于在服务端口之间共享。

Cluster 是什么?

  • 在服务器上同时启动多个进程
  • 每个进程里都跑的是同一份源代码(好比把以前一个进程的工作分给多个进程去做)
  • 更神奇的是,这些进程可以同时监听一个端口(具体原理推荐阅读 @DavidCai1993 这篇 Cluster 实现原理)。
  • 负责启动其他进程的叫做 Master 进程,他好比是个『包工头』,不做具体的工作,只负责启动其他进程。
  • 其他被启动的叫 Worker 进程,顾名思义就是干活的『工人』。它们接收请求,对外提供服务。
  • Worker 进程的数量一般根据服务器的 CPU 核数来定,这样就可以完美利用多核资源。workers = Number(process.argv[2] || require('os').cpus().length);

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

if (cluster.isMaster) {
  // Fork workers.
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  cluster.on('exit', function(worker, code, signal) {
    console.log('worker ' + worker.process.pid + ' died');
  });
} else {
  // Workers can share any TCP connection
  // In this case it is an HTTP server
  http.createServer(function(req, res) {
    res.writeHead(200);
    res.end("hello world\n");
  }).listen(8000);
}

参考:


解读Node.js的cluster模块
通过源码解析 Node.js 中 cluster 模块的主要功能实现
nodejs开发指南
cluster模块

点赞
收藏
评论区
推荐文章
马丁路德 马丁路德
4年前
浅谈 vue 前端同构框架 nuxt 及其性能优化
前言使用nuxt.js做项目也接近快一年了,从立项到内测、公测、再到正式上线,还有后面的不断维护,也陆陆续续的踩了很多坑,其中最大的问题就是node的渲染性能问题了。模板转换是cpu密集型的操作,node又是单线程的,并发一高,cpu就会飙到100%。为了提
Irene181 Irene181
4年前
一篇文章带你了解Python的分布式进程接口
一、前言    在Thread和Process中,应当优选Process,因为Process更稳定,而且,Process可以分布到多台机器上,而Thread最多只能分布到同一台机器的多个CPU上。Python的multiprocessing模块不但支持多进程,其中managers子模块还支持把多进程分布到多台机器上。可以写一个服务进程作为调度者,将任务分
亚瑟 亚瑟
4年前
为什么单线程的Redis能支持高并发?
一、Redis为什么是单线程注意:redis单线程指的是网络请求模块使用了一个线程,即一个线程处理所有网络请求,其他模块仍用了多个线程。因为CPU不是Redis的瓶颈。Redis的瓶颈最有可能是机器内存或者网络带宽,既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了。关于redis的性能,官方网站也有,普通笔记本轻松处理每秒几十万
Wesley13 Wesley13
4年前
K8S基础概念
一、核心概念1、NodeNode作为集群中的工作节点,运行真正的应用程序,在Node上Kubernetes管理的最小运行单元是Pod。Node上运行着Kubernetes的Kubelet、kubeproxy服务进程,这些服务进程负责Pod的创建、启动、监控、重启、销毁、以及实现软件模式的负载均衡。Node包含
Stella981 Stella981
4年前
Skynet Cluster 简介
SkynetCluster简介Cluster模块负责Skynet节点之间的通信。Cluster概述||node1||node2|<|
Stella981 Stella981
4年前
Node.js 多进程处理CPU密集任务
Node.js单线程与多进程大家都知道Node.js性能很高,是以异步事件驱动、非阻塞I/O而被广泛使用。但缺点也很明显,由于Node.js是单线程程序,如果长时间运算,会导致CPU不能及时释放,所以并不适合CPU密集型应用。当然,也不是没有办法解决这个问题。虽然Node.js不支持多线程,但
Stella981 Stella981
4年前
Kubernetes集群部署之五node节点部署
Node节点是Kubernetes集群中的工作负载节点.每个node都会被master分配一些工作负载,每个node节点都运行以下关键服务进程.Kubelet:负责pod对应的容器的创建、启停等任务,同时与master节点密切协作,实现集群管理的基本功能.Kubeproxy:实现kubernetesservice的通信与负载均衡机制的重要
Stella981 Stella981
4年前
Rabbitmq学习之路4
上一节学习了cluster,使得我们可以在一个cluster中同步各种消息,不过有时候我们需要把一个cluster的消息同步到另一个cluster中,比如线下测试,模仿用户真实数据。federation插件是一个在不需要cluster,而在brokers之间传输消息的高性能插件,federation插件可以在brokers或者cluster之间传输消
Stella981 Stella981
4年前
Noark入门之线程模型
0x00单线程多进程单线程与单进程多线程的目的都是想尽可能的利用CPU,减少CPU的空闲时间,特别是多核环境,今天咱不做深度解读,跳过...0x01线程池锁最早的一部分游戏服务器是采用线程池的方式来处理玩家的业务请求,以达最大限度的利用多核优势来提高处理业务能力。但线程池同时也带来了并发问题,为了解决同一玩家多个业务请求不被
Stella981 Stella981
4年前
Node.js 中使用 ECDSA 签名遇到的坑
文/Fenying最近有个朋友问我关于Node.js下使用ECDSA的问题,主要是使用Node.js的Crypto模块无法校验网络传输过来的签名结果。在踩坑无数后,终于搞清楚了原因。坑0x00:签名输出格式在排除了证书、消息不一致的可能之后,我开始对比使用Node.js签名的结果与网络传输过来的签
liam liam
2年前
Node.js实现文件夹遍历的常用方法
在开发中,经常需要对文件系统进行操作,包括遍历文件夹以获取文件列表。本文将讨论使用Node.js遍历文件夹的几种常用方法,并通过一个实际案例来演示如何实现。基本概念在开始之前,让我们了解一些基本的概念:文件系统模块(fs模块):Node.js提供了内置的f
拓朴薄雾
拓朴薄雾
Lv1
海上生明月,天涯共此时。
文章
4
粉丝
0
获赞
0