简体   繁体   中英

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

So I have been trying to understand how Node cluster works and I have this code:

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)
}

When I run this and then exit with Ctrl+C I receive this console output and my master process also dies.

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.

So it's doing what I'd like it to do, but why does the master process also die when all I'm having SIGINT do is kill the workers?

It helps to think about why any Node process stops.

For example if your Node program is one line:

console.log("Starting…stoping")

It will display the text and exit. But this stays alive:

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

The Node process keeps cycling through the event loop so long as there are things like timers or I/O events to deal with. Once there aren't any, the loop stops and the process ends.

So in your example the child process are staying alive because are listening to an open I/O connection from Express. The master cluster is alive because it is waiting for I/O events from the children. When the children die, there is nothing left in the poll queue for the master to do, so it exits. (lots more detail here: https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/ )

You can keep the master cluster running by giving something to do like:

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

Now the master will keep on ticking away ( and be annoying to stop because you're catching SIGINT ) even after the children exit.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM