当所有 Node worker 死亡时,集群主节点会发生什么?

What happens to the cluster master when all Node workers die?

所以我一直在尝试了解 Node 集群的工作原理并且我有这段代码:

const cluster = require('cluster')
const os = require('os')
const express = require('express')
const app = express()

let cpus

// Check to see if the master process is running this
if (cluster.isMaster) {
    console.log(`Master Process: ${process.pid} is running.`)

    // Get the number of CPU's and fork that many workers
    cpus = os.cpus().length
    for(let i = 0; i < cpus; i++) {
        console.log(`Forking process #${i+1}`)
        cluster.fork()
    }

    // If worker process is killed log it
    cluster.on('exit', (worker) => {
        console.log(`Worker ${worker.process.pid} died.`)
    })

    // Once a worker is connected output they are online
    cluster.on('online', (worker) => {
        console.log(`Worker ${worker.process.pid} is online.`)
    })

    process.on('SIGINT', () => {
        for(const id in cluster.workers) {
            cluster.workers[id].kill('SIGINT')
        }
    })
} else {
    // Each worker should listen on port 3000
    app.listen(3000)
}

当我 运行 然后以 Ctrl+C 退出时,我收到此控制台输出并且我的主进程也死了。

Master Process: 19988 is running.
Forking process #1
Forking process #2
Forking process #3
Forking process #4
Worker 14684 is online.
Worker 14672 is online.
Worker 12520 is online.
Worker 3276 is online.
Worker 3276 died.
Worker 12520 died.
Worker 14672 died.
Worker 14684 died.

所以它正在做我想做的事情,但是为什么主进程也死了,而我 SIGINT 所做的只是杀死工人?

这有助于思考为什么任何 Node 进程停止。

例如,如果您的 Node 程序是一行:

console.log("Starting…stoping")

它将显示文本并退出。但这还活着:

setInterval(() => console.log("still going"), 1000)

只要有定时器或 I/O 事件需要处理,Node 进程就会一直在事件循环中循环。一旦没有,循环停止,进程结束。

因此在您的示例中,child 进程保持活动状态,因为正在侦听来自 Express 的开放 I/O 连接。主集群处于活动状态,因为它正在等待来自 children 的 I/O 事件。当 children 死亡时,轮询队列中没有任何东西留给 master 做,所以它退出。 (此处有更多详细信息:https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/

您可以保留主集群 运行,方法如下:

if (cluster.isMaster) {
    console.log(`Master Process: ${process.pid} is running.`)
    setInterval(() => {
        console.log('Master still here')
    }, 1000)
   // ... etc
  }

现在 master 会继续滴答作响(并且因为你正在捕捉 SIGINT 而停下来很烦人)即使在 children 退出之后也是如此。