所以我一直在尝试了解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
的全部工作是杀死工人时,为什么主进程也消失了?
答案 0 :(得分: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而烦人地停下来)。