cluster模块
cluster概述
cluster模块是对process的封装,
- 使用该模块可以创建共享同一个端口的子进程。
- 实现子进程之间的负载均衡机制。
集群中的主进程称为Master, fork出的子进程成为Worker
api
cluster.fork
创建一个worker进程,返回一个Worker实例。
const worker = cluster.fork()
console.log(worker.process.pid) //打印子进程pid
cluster.workers
在primary(master)进程里调用,获取所有worker进程对应的Worker实例。
// 打印所有worker的状态
for (const worker of Object.values(cluster.workers)) {
console.log(`worker-${worker.id}|${worker.process.pid}|${worker.status}`);
}
官方文档里提到了一个有意思的点,一个worker会在触发disconnect和exit事件后,从workers集合里删除,但这2个事件本身发生的先后是不保证的。
cluser.isMaster/cluser.isPrimary/cluster.isWorker
这几个api用于判断当前进程上主进程还是fork出的worker进程。
- cluser.isMaster判断当前进程是否是主进程,若process.env.NODE_UNIQUE_ID为undefied,则为true。
- cluser.isPrimary功能和cluser.isMastery一致
- cluser.isWorker判断当前进程是否是worker进程
cluster.setupMaster/cluster.setupPrimary
// fork出的子进程运行worker.js, args是传递给进程的参数
cluster.setupPrimary({
exec: 'worker.js',
args: ['--use', 'https'],
silent: true,
});
cluster.on
cluster.on('disconnect', (worker) => {
// worker断开链接
});
cluster.on('exit', (worker) => {
// worker进程退出
});
cluster.on('fork', (worker) => {
// 新的worker进程被fork
});
cluster.on('listening', (worker) => {
// 新worker开始监听端口
});
cluster.on('message', (worker) => {
// 接受到来自worker消息
});
cluster.on('online', (worker) => {
// worker进程开始运行后,在fork事件之后
});
cluster.on('setup', () => {
// cluster.setupPrimary被调用
});
cluster多进程模型
生产环境多进程模型
这个模型解决了什么问题
- js只有一个主线程,无法充分利用的多核cpu的资源,通过cluster可以实现多进程模型
- 多个进程监需要监听多个端口,通过cluster创建多子进程和主进程可以共享同一个端口(主进程监听,通过进程通信转发给子进程)
子进程创建
使用cluster.fork创建一个worker进程,cluster.workers可以获取所有的woker进程。
端口监听
master进程创建socket,与端口绑定, 子进程的listen方法实际上上被hack了的。
负载均衡策略
可以通过改变cluster.schedulingPolicy的值设置采用的负载均衡策略,这部分简单介绍rr策略(时片轮转法)。
round-robin 时间片轮转法
默认采用的策略是 round-robin 时间片轮转法, 该算法是把请求依次分配个每个用户,从序号1 ~ 序号Max,然后再进入新的循环。(这本身是一个进程调度算法,将一个较小时间单元定义为时间量或时间片。时间片的大小通常为 10~100ms,没有一个会占有CPU超过一个时间片,除非它是唯一可执行的进程。)
worker1 process1 pid=1
worker2 process2 pid=2
worker3 process2 pid=3
主进程会分别把很小时间内的所有请求转发worker进程, 其顺序为worker1-worker2-worker3,然后再从worker1开始。
这个策略默认所有用户的处理能力是相同的,所以如果各个用户的性能存在差异,会出现负载不均衡的情况。
weight-round-robin 加权轮转法
在时片轮转法的基础上给每个用户分配不同的权重,来调整每个用户被分配次数占总数的比例,以应对每个用户处理能力不同的实际场景。
process1 pid=1 weight=1
process2 pid=2 weight=1
process2 pid=3 weight=98
当分配次数非常大时,进程123被分配到的次数占总数比例分别趋近1%, 1%, 98%。
pm2
一个node应用的进程管理器,内置负载均衡等功能。 生产部署node应用时,因为nodejs是单线程,一台机器上通常需要跑拉起进程来一利用计算资源。
Pm2解决的问题:
1.拉起和管理多个应用进程,并管理它们的状态,让你的程序在生产环境始终保持活跃状态。
2.负载均衡,主进程接受请求,通过IPC方式转发给子进程处理。