结论
虽然平常通过设置为CPU进程数的工作进程,但是可以超过这个数,并且并不是主进程先创建
if (cluster.isMaster) {
// 循环 fork 任务 CPU i5-7300HQ 四核四进程
for (let i = 0; i < 6; i++) {
cluster.fork()
}
console.log(chalk.green(`主进程运行在${process.pid}`))
} else {
app.listen(1314) // export app 一个 Koa 服务器的实例
console.log(chalk.green(`子进程运行在${process.pid}`))
}
#子进程运行在17768
#子进程运行在5784
#子进程运行在11232
#子进程运行在7904
#主进程运行在12960
#子进程运行在4300
#子进程运行在16056在主进程中 cluster 表示主进程(用于监听、发送事件), process 是本身的进程,worker 表示子进程,通过 cluster.workers 获取
在子进程中 process 表示子进程(用于监听、发送事件),也可以通过 cluster.worker 表示当前子进程
cluster.worker.process 等价于 process(在子进程中)
主进程子进程相互通信

cluster 用于监听 process(child) 子进程触发的各种事件
worker 在主进程中获取,用于和自身通信。当子进程触发事件时,会返回当前的 worker 以及相关的信息到主进程相应的事件中
process(parent) 主进程本身的进程实例,在通信过程中基本没有用到
process(child) 子进程本身的实例,只能在子进程获取用于监听自身的事件
可见主进程与子进程通过这样一个三角关系互相通信,其中 cluster 和 worker 是在主进程中获取的,process(child) 是子进程。 cluster 通过操作 worker 通知子进程,子进程本身和 cluster 进行通信。为什么要这样设计呢?因为子进程会有多个,只有通过 worker 才能选择和哪个进程通信
子进程的调度策略 cluster.schedulingPolicy
调度策略,包括循环计数的 cluster.SCHED_RR,以及由操作系统决定的cluster.SCHED_NONE。 这是一个全局设置,当第一个工作进程被衍生或者调动cluster.setupMaster()时,都将第一时间生效。除Windows外的所有操作系统中,SCHED_RR都是默认设置。只要libuv可以有效地分发IOCP handle,而不会导致严重的性能冲击的话,Windows系统也会更改为SCHED_RR。cluster.schedulingPolicy 可以通过设置NODE_CLUSTER_SCHED_POLICY环境变量来实现。这个环境变量的有效值包括”rr” 和 “none”。
RR 即 Round-Robin 轮询调度,即每个子进程的获取的事件的机会是均等的,这是除 windows以外默认的。而 windows 下的调度策略很诡异,见下图。目前并没有相关 API 可以设置调度策略的算法,node 只为我们提供了两个值









