0

因此,我一直在尝试了解 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所要做的就是杀死工人时,为什么主进程也会死?

4

1 回答 1

1

思考为什么任何 Node 进程停止是有帮助的。

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

console.log("Starting…stoping")

它将显示文本并退出。但这仍然存在:

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

只要有诸如计时器或 I/O 事件之类的事情需要处理,Node 进程就会在事件循环中不断循环。一旦没有,循环停止并且过程结束。

因此,在您的示例中,子进程保持活动状态,因为正在侦听来自 Express 的打开 I/O 连接。主集群处于活动状态,因为它正在等待来自子节点的 I/O 事件。当孩子们死后,轮询队列中没有任何东西可供主人做,所以它退出。(这里有更多详细信息: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
  }

现在,即使在孩子们退出后,主人也会继续滴答作响(并且因为你正在捕捉 SIGINT 而令人讨厌停止)。

于 2018-07-06T18:55:16.330 回答