Skip to content

Cluster

[Stable: 2 - Stable]

Stable: 2 Stability: 2 - Estável

Código-fonte: lib/cluster.js

Clusters de processos Node.js podem ser usados para executar múltiplas instâncias do Node.js que podem distribuir cargas de trabalho entre os seus threads de aplicação. Quando o isolamento de processos não é necessário, use o módulo worker_threads em vez disso, o qual permite executar múltiplos threads de aplicação dentro de uma única instância do Node.js.

O módulo cluster permite a fácil criação de processos filhos que todos compartilham portas de servidor.

js
import cluster from 'node:cluster'
import http from 'node:http'
import { availableParallelism } from 'node:os'
import process from 'node:process'

const numCPUs = availableParallelism()

if (cluster.isPrimary) {
  console.log(`Primário ${process.pid} está rodando`)

  // Criar workers.
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork()
  }

  cluster.on('exit', (worker, code, signal) => {
    console.log(`worker ${worker.process.pid} morreu`)
  })
} else {
  // Workers podem compartilhar qualquer conexão TCP
  // Neste caso é um servidor HTTP
  http
    .createServer((req, res) => {
      res.writeHead(200)
      res.end('olá mundo\n')
    })
    .listen(8000)

  console.log(`Worker ${process.pid} iniciado`)
}
js
const cluster = require('node:cluster')
const http = require('node:http')
const numCPUs = require('node:os').availableParallelism()
const process = require('node:process')

if (cluster.isPrimary) {
  console.log(`Primário ${process.pid} está rodando`)

  // Criar workers.
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork()
  }

  cluster.on('exit', (worker, code, signal) => {
    console.log(`worker ${worker.process.pid} morreu`)
  })
} else {
  // Workers podem compartilhar qualquer conexão TCP
  // Neste caso é um servidor HTTP
  http
    .createServer((req, res) => {
      res.writeHead(200)
      res.end('olá mundo\n')
    })
    .listen(8000)

  console.log(`Worker ${process.pid} iniciado`)
}

Executar o Node.js agora irá compartilhar a porta 8000 entre os workers:

bash
$ node server.js
Primário 3596 está rodando
Worker 4324 iniciado
Worker 4520 iniciado
Worker 6056 iniciado
Worker 5644 iniciado

No Windows, ainda não é possível configurar um servidor de named pipe em um worker.

Como funciona

Os processos de trabalho são gerados usando o método child_process.fork(), para que possam se comunicar com o processo pai via IPC e passar handles de servidor de um lado para o outro.

O módulo cluster suporta dois métodos de distribuição de conexões de entrada.

O primeiro (e o padrão em todas as plataformas, exceto Windows) é a abordagem round-robin, onde o processo primário escuta em uma porta, aceita novas conexões e as distribui entre os trabalhadores em um padrão round-robin, com algumas inteligências integradas para evitar sobrecarregar um processo de trabalho.

A segunda abordagem é onde o processo primário cria o socket de escuta e o envia para os trabalhadores interessados. Os trabalhadores então aceitam conexões de entrada diretamente.

A segunda abordagem deve, em teoria, fornecer o melhor desempenho. Na prática, no entanto, a distribuição tende a ser muito desequilibrada devido às variações do agendador do sistema operacional. Cargas foram observadas onde mais de 70% de todas as conexões acabaram em apenas dois processos, de um total de oito.

Como server.listen() transfere a maior parte do trabalho para o processo primário, existem três casos em que o comportamento entre um processo normal do Node.js e um trabalhador cluster difere:

O Node.js não fornece lógica de roteamento. Portanto, é importante projetar um aplicativo de forma que ele não dependa muito de objetos de dados na memória para coisas como sessões e login.

Como os trabalhadores são todos processos separados, eles podem ser eliminados ou reaparecidos dependendo das necessidades de um programa, sem afetar outros trabalhadores. Enquanto houver alguns trabalhadores ainda vivos, o servidor continuará a aceitar conexões. Se nenhum trabalhador estiver vivo, as conexões existentes serão descartadas e novas conexões serão recusadas. No entanto, o Node.js não gerencia automaticamente o número de trabalhadores. É responsabilidade do aplicativo gerenciar o pool de trabalhadores com base em suas próprias necessidades.

Embora um caso de uso principal para o módulo node:cluster seja o trabalho em rede, ele também pode ser usado para outros casos de uso que exigem processos de trabalho.

Classe: Worker

Adicionado em: v0.7.0

Um objeto Worker contém todas as informações e métodos públicos sobre um worker. No primário, ele pode ser obtido usando cluster.workers. Em um worker, ele pode ser obtido usando cluster.worker.

Evento: 'disconnect'

Adicionado em: v0.7.7

Semelhante ao evento cluster.on('disconnect'), mas específico para este worker.

js
cluster.fork().on('disconnect', () => {
  // Worker desconectou
})

Evento: 'error'

Adicionado em: v0.7.3

Este evento é o mesmo fornecido por child_process.fork().

Dentro de um worker, process.on('error') também pode ser usado.

Evento: 'exit'

Adicionado em: v0.11.2

  • code <number> O código de saída, se ele saiu normalmente.
  • signal <string> O nome do sinal (por exemplo, 'SIGHUP') que fez com que o processo fosse encerrado.

Semelhante ao evento cluster.on('exit'), mas específico para este worker.

js
import cluster from 'node:cluster'

if (cluster.isPrimary) {
  const worker = cluster.fork()
  worker.on('exit', (code, signal) => {
    if (signal) {
      console.log(`worker foi encerrado pelo sinal: ${signal}`)
    } else if (code !== 0) {
      console.log(`worker saiu com o código de erro: ${code}`)
    } else {
      console.log('worker com sucesso!')
    }
  })
}
js
const cluster = require('node:cluster')

if (cluster.isPrimary) {
  const worker = cluster.fork()
  worker.on('exit', (code, signal) => {
    if (signal) {
      console.log(`worker foi encerrado pelo sinal: ${signal}`)
    } else if (code !== 0) {
      console.log(`worker saiu com o código de erro: ${code}`)
    } else {
      console.log('worker com sucesso!')
    }
  })
}

Evento: 'listening'

Adicionado em: v0.7.0

Semelhante ao evento cluster.on('listening'), mas específico para este worker.

js
cluster.fork().on('listening', address => {
  // Worker está ouvindo
})
js
cluster.fork().on('listening', address => {
  // Worker está ouvindo
})

Não é emitido no worker.

Evento: 'message'

Adicionado em: v0.7.0

Semelhante ao evento 'message' do cluster, mas específico para este worker.

Dentro de um worker, process.on('message') também pode ser usado.

Veja process evento: 'message'.

Aqui está um exemplo usando o sistema de mensagens. Ele mantém uma contagem no processo principal do número de solicitações HTTP recebidas pelos workers:

js
import cluster from 'node:cluster'
import http from 'node:http'
import { availableParallelism } from 'node:os'
import process from 'node:process'

if (cluster.isPrimary) {
  // Controlar as solicitações http
  let numReqs = 0
  setInterval(() => {
    console.log(`numReqs = ${numReqs}`)
  }, 1000)

  // Contar solicitações
  function messageHandler(msg) {
    if (msg.cmd && msg.cmd === 'notifyRequest') {
      numReqs += 1
    }
  }

  // Iniciar workers e ouvir mensagens contendo notifyRequest
  const numCPUs = availableParallelism()
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork()
  }

  for (const id in cluster.workers) {
    cluster.workers[id].on('message', messageHandler)
  }
} else {
  // Os processos Worker têm um servidor http.
  http
    .Server((req, res) => {
      res.writeHead(200)
      res.end('olá mundo\n')

      // Notificar o processo principal sobre a solicitação
      process.send({ cmd: 'notifyRequest' })
    })
    .listen(8000)
}
js
const cluster = require('node:cluster')
const http = require('node:http')
const numCPUs = require('node:os').availableParallelism()
const process = require('node:process')

if (cluster.isPrimary) {
  // Controlar as solicitações http
  let numReqs = 0
  setInterval(() => {
    console.log(`numReqs = ${numReqs}`)
  }, 1000)

  // Contar solicitações
  function messageHandler(msg) {
    if (msg.cmd && msg.cmd === 'notifyRequest') {
      numReqs += 1
    }
  }

  // Iniciar workers e ouvir mensagens contendo notifyRequest
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork()
  }

  for (const id in cluster.workers) {
    cluster.workers[id].on('message', messageHandler)
  }
} else {
  // Os processos Worker têm um servidor http.
  http
    .Server((req, res) => {
      res.writeHead(200)
      res.end('olá mundo\n')

      // Notificar o processo principal sobre a solicitação
      process.send({ cmd: 'notifyRequest' })
    })
    .listen(8000)
}

Evento: 'online'

Adicionado em: v0.7.0

Semelhante ao evento cluster.on('online'), mas específico para este worker.

js
cluster.fork().on('online', () => {
  // Worker está online
})

Não é emitido no worker.

worker.disconnect()

[Histórico]

VersãoAlterações
v7.3.0Este método agora retorna uma referência para worker.
v0.7.7Adicionado em: v0.7.7

Em um worker, esta função irá fechar todos os servidores, aguardar o evento 'close' nesses servidores e, em seguida, desconectar o canal IPC.

No primário, uma mensagem interna é enviada ao worker, fazendo com que ele chame .disconnect() em si mesmo.

Faz com que .exitedAfterDisconnect seja definido.

Depois que um servidor é fechado, ele não aceitará mais novas conexões, mas as conexões podem ser aceitas por qualquer outro worker em escuta. As conexões existentes poderão ser fechadas normalmente. Quando não houver mais conexões, veja server.close(), o canal IPC para o worker será fechado, permitindo que ele morra normalmente.

O acima se aplica apenas a conexões de servidor, as conexões de cliente não são fechadas automaticamente por workers, e o desconectar não espera que elas fechem antes de sair.

Em um worker, process.disconnect existe, mas não é esta função; é disconnect().

Como conexões de servidor de longa duração podem impedir que os workers se desconectem, pode ser útil enviar uma mensagem, para que ações específicas do aplicativo possam ser tomadas para fechá-las. Também pode ser útil implementar um tempo limite, matando um worker se o evento 'disconnect' não tiver sido emitido após algum tempo.

js
if (cluster.isPrimary) {
  const worker = cluster.fork()
  let timeout

  worker.on('listening', address => {
    worker.send('shutdown')
    worker.disconnect()
    timeout = setTimeout(() => {
      worker.kill()
    }, 2000)
  })

  worker.on('disconnect', () => {
    clearTimeout(timeout)
  })
} else if (cluster.isWorker) {
  const net = require('node:net')
  const server = net.createServer(socket => {
    // Conexões nunca terminam
  })

  server.listen(8000)

  process.on('message', msg => {
    if (msg === 'shutdown') {
      // Iniciar o fechamento normal de quaisquer conexões com o servidor
    }
  })
}

worker.exitedAfterDisconnect

Adicionado em: v6.0.0

Esta propriedade é true se o worker saiu devido a .disconnect(). Se o worker saiu de qualquer outra forma, é false. Se o worker não saiu, é undefined.

O booleano worker.exitedAfterDisconnect permite distinguir entre saída voluntária e acidental, o primário pode optar por não reiniciar um worker com base nesse valor.

js
cluster.on('exit', (worker, code, signal) => {
  if (worker.exitedAfterDisconnect === true) {
    console.log('Oh, foi apenas voluntário – não há necessidade de se preocupar')
  }
})

// matar worker
worker.kill()

worker.id

Adicionado em: v0.8.0

Cada novo worker recebe seu próprio id exclusivo, este id é armazenado em id.

Enquanto um worker está ativo, esta é a chave que o indexa em cluster.workers.

worker.isConnected()

Adicionado em: v0.11.14

Esta função retorna true se o worker estiver conectado ao seu primário através do seu canal IPC, false caso contrário. Um worker é conectado ao seu primário após ter sido criado. Ele é desconectado após o evento 'disconnect' ser emitido.

worker.isDead()

Adicionado em: v0.11.14

Esta função retorna true se o processo do worker foi encerrado (seja por ter saído ou por ter sido sinalizado). Caso contrário, retorna false.

js
import cluster from 'node:cluster'
import http from 'node:http'
import { availableParallelism } from 'node:os'
import process from 'node:process'

const numCPUs = availableParallelism()

if (cluster.isPrimary) {
  console.log(`Primário ${process.pid} está em execução`)

  // Criar workers.
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork()
  }

  cluster.on('fork', worker => {
    console.log('worker está morto:', worker.isDead())
  })

  cluster.on('exit', (worker, code, signal) => {
    console.log('worker está morto:', worker.isDead())
  })
} else {
  // Workers podem compartilhar qualquer conexão TCP. Neste caso, é um servidor HTTP.
  http
    .createServer((req, res) => {
      res.writeHead(200)
      res.end(`Processo atual\n ${process.pid}`)
      process.kill(process.pid)
    })
    .listen(8000)
}
js
const cluster = require('node:cluster')
const http = require('node:http')
const numCPUs = require('node:os').availableParallelism()
const process = require('node:process')

if (cluster.isPrimary) {
  console.log(`Primário ${process.pid} está em execução`)

  // Criar workers.
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork()
  }

  cluster.on('fork', worker => {
    console.log('worker está morto:', worker.isDead())
  })

  cluster.on('exit', (worker, code, signal) => {
    console.log('worker está morto:', worker.isDead())
  })
} else {
  // Workers podem compartilhar qualquer conexão TCP. Neste caso, é um servidor HTTP.
  http
    .createServer((req, res) => {
      res.writeHead(200)
      res.end(`Processo atual\n ${process.pid}`)
      process.kill(process.pid)
    })
    .listen(8000)
}

worker.kill([signal])

Adicionado em: v0.9.12

  • signal <string> Nome do sinal de interrupção a ser enviado para o processo do worker. Padrão: 'SIGTERM'

Esta função irá interromper o worker. No worker primário, faz isso desconectando o worker.process e, uma vez desconectado, interrompendo com signal. No worker, faz isso interrompendo o processo com signal.

A função kill() interrompe o processo do worker sem esperar por uma desconexão graciosa, tendo o mesmo comportamento que worker.process.kill().

Este método é um alias de worker.destroy() para compatibilidade retroativa.

Em um worker, process.kill() existe, mas não é esta função; é kill().

worker.process

Adicionado em: v0.7.0

Todos os workers são criados usando child_process.fork(), o objeto retornado desta função é armazenado como .process. Em um worker, o process global é armazenado.

Veja: Módulo Child Process.

Os workers chamarão process.exit(0) se o evento 'disconnect' ocorrer em process e .exitedAfterDisconnect não for true. Isso protege contra desconexões acidentais.

worker.send(message[, sendHandle[, options]][, callback])

[Histórico]

VersãoMudanças
v4.0.0O parâmetro callback agora é suportado.
v0.7.0Adicionado em: v0.7.0
  • message <Object>
  • sendHandle <Handle>
  • options <Object> O argumento options, se presente, é um objeto usado para parametrizar o envio de certos tipos de handles. options suporta as seguintes propriedades:
    • keepOpen <boolean> Um valor que pode ser usado ao passar instâncias de net.Socket. Quando true, o socket é mantido aberto no processo de envio. Padrão: false.
  • callback <Function>
  • Retorna: <boolean>

Envia uma mensagem para um worker ou primário, opcionalmente com um handle.

No primário, isso envia uma mensagem para um worker específico. É idêntico a ChildProcess.send().

Em um worker, isso envia uma mensagem para o primário. É idêntico a process.send().

Este exemplo irá ecoar todas as mensagens do primário:

js
if (cluster.isPrimary) {
  const worker = cluster.fork()
  worker.send('oi')
} else if (cluster.isWorker) {
  process.on('message', msg => {
    process.send(msg)
  })
}

Evento: 'disconnect'

Adicionado em: v0.7.9

Emitido após o canal IPC do worker ser desconectado. Isso pode ocorrer quando um worker sai normalmente, é encerrado ou é desconectado manualmente (como com worker.disconnect()).

Pode haver um atraso entre os eventos 'disconnect' e 'exit'. Esses eventos podem ser usados para detectar se o processo está preso em uma limpeza ou se existem conexões de longa duração.

js
cluster.on('disconnect', worker => {
  console.log(`O worker #${worker.id} foi desconectado`)
})

Evento: 'exit'

Adicionado em: v0.7.9

  • worker <cluster.Worker>
  • code <number> O código de saída, se saiu normalmente.
  • signal <string> O nome do sinal (por exemplo, 'SIGHUP') que fez com que o processo fosse encerrado.

Quando qualquer um dos workers morre, o módulo cluster emitirá o evento 'exit'.

Isso pode ser usado para reiniciar o worker chamando .fork() novamente.

js
cluster.on('exit', (worker, code, signal) => {
  console.log('worker %d morreu (%s). reiniciando...', worker.process.pid, signal || code)
  cluster.fork()
})

Consulte o evento child_process event: 'exit'.

Evento: 'fork'

Adicionado em: v0.7.0

Quando um novo worker é bifurcado, o módulo cluster emitirá um evento 'fork'. Isso pode ser usado para registrar a atividade do worker e criar um tempo limite personalizado.

js
const timeouts = []
function errorMsg() {
  console.error('Algo deve estar errado com a conexão ...')
}

cluster.on('fork', worker => {
  timeouts[worker.id] = setTimeout(errorMsg, 2000)
})
cluster.on('listening', (worker, address) => {
  clearTimeout(timeouts[worker.id])
})
cluster.on('exit', (worker, code, signal) => {
  clearTimeout(timeouts[worker.id])
  errorMsg()
})

Evento: 'listening'

Adicionado em: v0.7.0

Após chamar listen() de um worker, quando o evento 'listening' é emitido no servidor, um evento 'listening' também será emitido no cluster no principal.

O manipulador de eventos é executado com dois argumentos, o worker contém o objeto worker e o objeto address contém as seguintes propriedades de conexão: address, port e addressType. Isso é muito útil se o worker estiver escutando em mais de um endereço.

js
cluster.on('listening', (worker, address) => {
  console.log(`Um worker agora está conectado a ${address.address}:${address.port}`)
})

O addressType é um dos seguintes:

  • 4 (TCPv4)
  • 6 (TCPv6)
  • -1 (socket de domínio Unix)
  • 'udp4' ou 'udp6' (UDPv4 ou UDPv6)

Evento: 'message'

[Histórico]

VersãoMudanças
v6.0.0O parâmetro worker é passado agora; veja abaixo para detalhes.
v2.5.0Adicionado em: v2.5.0

Emitido quando o cluster principal recebe uma mensagem de qualquer worker.

Veja o evento child_process event: 'message'.

Evento: 'online'

Adicionado em: v0.7.0

Após criar um novo worker, o worker deve responder com uma mensagem online. Quando o principal recebe uma mensagem online, ele emitirá este evento. A diferença entre 'fork' e 'online' é que fork é emitido quando o principal cria um worker, e 'online' é emitido quando o worker está em execução.

js
cluster.on('online', worker => {
  console.log('Eba, o worker respondeu após ser criado')
})

Evento: 'setup'

Adicionado em: v0.7.1

Emitido sempre que .setupPrimary() é chamado.

O objeto settings é o objeto cluster.settings no momento em que .setupPrimary() foi chamado e é apenas consultivo, pois várias chamadas para .setupPrimary() podem ser feitas em um único tick.

Se a precisão for importante, use cluster.settings.

cluster.disconnect([callback])

Adicionado em: v0.7.7

  • callback <Função> Chamada quando todos os workers são desconectados e os manipuladores são fechados.

Chama .disconnect() em cada worker em cluster.workers.

Quando eles são desconectados, todos os manipuladores internos serão fechados, permitindo que o processo primário termine normalmente se nenhum outro evento estiver aguardando.

O método aceita um argumento de callback opcional que será chamado quando terminar.

Isso só pode ser chamado do processo primário.

cluster.fork([env])

Adicionado em: v0.6.0

Cria um novo processo worker.

Isso só pode ser chamado do processo primário.

cluster.isMaster

Adicionado em: v0.8.1

Obsoleto desde: v16.0.0

[Estável: 0 - Obsoleto]

Estável: 0 Estabilidade: 0 - Obsoleto

Alias obsoleto para cluster.isPrimary.

cluster.isPrimary

Adicionado em: v16.0.0

Verdadeiro se o processo for primário. Isso é determinado por process.env.NODE_UNIQUE_ID. Se process.env.NODE_UNIQUE_ID não estiver definido, então isPrimary é true.

cluster.isWorker

Adicionado em: v0.6.0

Verdadeiro se o processo não for primário (é a negação de cluster.isPrimary).

cluster.schedulingPolicy

Adicionado em: v0.11.2

A política de agendamento, seja cluster.SCHED_RR para round-robin ou cluster.SCHED_NONE para deixar para o sistema operacional. Esta é uma configuração global e efetivamente congelada assim que o primeiro worker é gerado ou .setupPrimary() é chamado, o que acontecer primeiro.

SCHED_RR é o padrão em todos os sistemas operacionais, exceto no Windows. O Windows mudará para SCHED_RR assim que o libuv for capaz de distribuir efetivamente os handles IOCP sem incorrer em uma grande perda de desempenho.

cluster.schedulingPolicy também pode ser definido através da variável de ambiente NODE_CLUSTER_SCHED_POLICY. Os valores válidos são 'rr' e 'none'.

cluster.settings

[Histórico]

VersãoMudanças
v13.2.0, v12.16.0A opção serialization agora é suportada.
v9.5.0A opção cwd agora é suportada.
v9.4.0A opção windowsHide agora é suportada.
v8.2.0A opção inspectPort agora é suportada.
v6.4.0A opção stdio agora é suportada.
v0.7.1Adicionado em: v0.7.1
  • <Object>
    • execArgv <string[]> Lista de argumentos de string passados para o executável Node.js. Padrão: process.execArgv.
    • exec <string> Caminho do arquivo para o arquivo de worker. Padrão: process.argv[1].
    • args <string[]> Argumentos de string passados para o worker. Padrão: process.argv.slice(2).
    • cwd <string> Diretório de trabalho atual do processo worker. Padrão: undefined (herda do processo pai).
    • serialization <string> Especifica o tipo de serialização usado para enviar mensagens entre processos. Os valores possíveis são 'json' e 'advanced'. Veja Serialização avançada para child_process para mais detalhes. Padrão: false.
    • silent <boolean> Se deve ou não enviar a saída para o stdio do pai. Padrão: false.
    • stdio <Array> Configura o stdio dos processos bifurcados. Como o módulo cluster depende do IPC para funcionar, esta configuração deve conter uma entrada 'ipc'. Quando esta opção é fornecida, ela substitui silent. Veja child_process.spawn()'s stdio.
    • uid <number> Define a identidade do usuário do processo. (Veja setuid(2).)
    • gid <number> Define a identidade do grupo do processo. (Veja setgid(2).)
    • inspectPort <number> | <Function> Define a porta do inspetor do worker. Este pode ser um número ou uma função que não recebe argumentos e retorna um número. Por padrão, cada worker recebe sua própria porta, incrementada a partir de process.debugPort do primário.
    • windowsHide <boolean> Oculta a janela do console dos processos bifurcados que normalmente seria criada em sistemas Windows. Padrão: false.

Após chamar .setupPrimary() (ou .fork()) este objeto de configurações conterá as configurações, incluindo os valores padrão.

Este objeto não se destina a ser alterado ou definido manualmente.

cluster.setupMaster([settings])

[Histórico]

VersãoMudanças
v16.0.0Obsoleto desde: v16.0.0
v6.4.0A opção stdio é suportada agora.
v0.7.1Adicionado em: v0.7.1

[Estável: 0 - Obsoleto]

Estável: 0 Estabilidade: 0 - Obsoleto

Alias obsoleto para .setupPrimary().

cluster.setupPrimary([settings])

Adicionado em: v16.0.0

setupPrimary é usado para alterar o comportamento padrão de 'fork'. Uma vez chamado, as configurações estarão presentes em cluster.settings.

Quaisquer alterações nas configurações afetam apenas as chamadas futuras para .fork() e não têm efeito sobre os workers que já estão em execução.

O único atributo de um worker que não pode ser definido via .setupPrimary() é o env passado para .fork().

Os padrões acima se aplicam apenas à primeira chamada; os padrões para chamadas posteriores são os valores atuais no momento em que cluster.setupPrimary() é chamado.

js
import cluster from 'node:cluster'

cluster.setupPrimary({
  exec: 'worker.js',
  args: ['--use', 'https'],
  silent: true,
})
cluster.fork() // worker https
cluster.setupPrimary({
  exec: 'worker.js',
  args: ['--use', 'http'],
})
cluster.fork() // worker http
js
const cluster = require('node:cluster')

cluster.setupPrimary({
  exec: 'worker.js',
  args: ['--use', 'https'],
  silent: true,
})
cluster.fork() // worker https
cluster.setupPrimary({
  exec: 'worker.js',
  args: ['--use', 'http'],
})
cluster.fork() // worker http

Isso só pode ser chamado a partir do processo primário.

cluster.worker

Adicionado em: v0.7.0

Uma referência ao objeto worker atual. Não disponível no processo primário.

js
import cluster from 'node:cluster'

if (cluster.isPrimary) {
  console.log('Eu sou o primário')
  cluster.fork()
  cluster.fork()
} else if (cluster.isWorker) {
  console.log(`Eu sou o worker #${cluster.worker.id}`)
}
js
const cluster = require('node:cluster')

if (cluster.isPrimary) {
  console.log('Eu sou o primário')
  cluster.fork()
  cluster.fork()
} else if (cluster.isWorker) {
  console.log(`Eu sou o worker #${cluster.worker.id}`)
}

cluster.workers

Adicionado em: v0.7.0

Um hash que armazena os objetos de worker ativos, indexados pelo campo id. Isso facilita a iteração por todos os workers. Ele está disponível apenas no processo primário.

Um worker é removido de cluster.workers depois que o worker é desconectado e sai. A ordem entre esses dois eventos não pode ser determinada com antecedência. No entanto, é garantido que a remoção da lista cluster.workers ocorra antes que o último evento 'disconnect' ou 'exit' seja emitido.

js
import cluster from 'node:cluster'

for (const worker of Object.values(cluster.workers)) {
  worker.send('grande anúncio para todos os workers')
}
js
const cluster = require('node:cluster')

for (const worker of Object.values(cluster.workers)) {
  worker.send('grande anúncio para todos os workers')
}