Skip to content

Cluster

[Estable: 2 - Estable]

Estable: 2 Estabilidad: 2 - Estable

Código fuente: lib/cluster.js

Los clústeres de procesos Node.js se pueden usar para ejecutar varias instancias de Node.js que pueden distribuir las cargas de trabajo entre sus hilos de aplicación. Cuando no se necesita el aislamiento del proceso, utilice el módulo worker_threads en su lugar, que permite ejecutar varios hilos de aplicación dentro de una sola instancia de Node.js.

El módulo cluster permite la creación sencilla de procesos secundarios que comparten puertos 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(`Principal ${process.pid} está en ejecución`)

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

  cluster.on('exit', (worker, code, signal) => {
    console.log(`worker ${worker.process.pid} murió`)
  })
} else {
  // Los workers pueden compartir cualquier conexión TCP
  // En este caso es un servidor HTTP
  http
    .createServer((req, res) => {
      res.writeHead(200)
      res.end('hello world\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(`Principal ${process.pid} está en ejecución`)

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

  cluster.on('exit', (worker, code, signal) => {
    console.log(`worker ${worker.process.pid} murió`)
  })
} else {
  // Los workers pueden compartir cualquier conexión TCP
  // En este caso es un servidor HTTP
  http
    .createServer((req, res) => {
      res.writeHead(200)
      res.end('hello world\n')
    })
    .listen(8000)

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

Ejecutar Node.js ahora compartirá el puerto 8000 entre los workers:

bash
$ node server.js
Principal 3596 está en ejecución
Worker 4324 iniciado
Worker 4520 iniciado
Worker 6056 iniciado
Worker 5644 iniciado

En Windows, todavía no es posible configurar un servidor de tuberías nombradas en un worker.

Cómo funciona

Los procesos de trabajo se generan usando el método child_process.fork(), para que puedan comunicarse con el padre a través de IPC e intercambiar manejadores de servidor.

El módulo cluster admite dos métodos para distribuir las conexiones entrantes.

El primero (y el predeterminado en todas las plataformas excepto Windows) es el enfoque de round-robin, donde el proceso principal escucha en un puerto, acepta nuevas conexiones y las distribuye entre los trabajadores en un ciclo redondo, con algunas funciones integradas para evitar sobrecargar un proceso de trabajo.

El segundo enfoque consiste en que el proceso principal crea el socket de escucha y lo envía a los trabajadores interesados. Los trabajadores luego aceptan las conexiones entrantes directamente.

El segundo enfoque, en teoría, debería proporcionar el mejor rendimiento. Sin embargo, en la práctica, la distribución tiende a ser muy desequilibrada debido a las vicisitudes del programador del sistema operativo. Se han observado cargas en las que más del 70% de todas las conexiones terminaron en solo dos procesos, de un total de ocho.

Debido a que server.listen() delega la mayor parte del trabajo al proceso principal, hay tres casos en los que el comportamiento entre un proceso Node.js normal y un trabajador de clúster difiere:

Node.js no proporciona lógica de enrutamiento. Por lo tanto, es importante diseñar una aplicación de manera que no dependa demasiado de los objetos de datos en memoria para cosas como sesiones e inicio de sesión.

Debido a que todos los trabajadores son procesos separados, se pueden matar o volver a generar según las necesidades de un programa, sin afectar a otros trabajadores. Mientras haya algunos trabajadores vivos, el servidor continuará aceptando conexiones. Si no hay trabajadores vivos, se descartarán las conexiones existentes y se rechazarán las nuevas conexiones. Sin embargo, Node.js no gestiona automáticamente el número de trabajadores. Es responsabilidad de la aplicación gestionar el grupo de trabajadores en función de sus propias necesidades.

Aunque un caso de uso principal del módulo node:cluster es la creación de redes, también se puede utilizar para otros casos de uso que requieren procesos de trabajo.

Clase: Worker

Añadido en: v0.7.0

Un objeto Worker contiene toda la información pública y el método sobre un trabajador. En el principal se puede obtener usando cluster.workers. En un trabajador se puede obtener usando cluster.worker.

Evento: 'disconnect'

Añadido en: v0.7.7

Similar al evento cluster.on('disconnect'), pero específico para este trabajador.

js
cluster.fork().on('disconnect', () => {
  // El trabajador se ha desconectado
})

Evento: 'error'

Añadido en: v0.7.3

Este evento es el mismo que el proporcionado por child_process.fork().

Dentro de un trabajador, también se puede usar process.on('error').

Evento: 'exit'

Añadido en: v0.11.2

  • code <number> El código de salida, si salió normalmente.
  • signal <string> El nombre de la señal (por ejemplo, 'SIGHUP') que causó que el proceso fuera eliminado.

Similar al evento cluster.on('exit'), pero específico para este trabajador.

js
import cluster from 'node:cluster'

if (cluster.isPrimary) {
  const worker = cluster.fork()
  worker.on('exit', (code, signal) => {
    if (signal) {
      console.log(`el trabajador fue eliminado por la señal: ${signal}`)
    } else if (code !== 0) {
      console.log(`el trabajador salió con el código de error: ${code}`)
    } else {
      console.log('¡trabajador exitoso!')
    }
  })
}
js
const cluster = require('node:cluster')

if (cluster.isPrimary) {
  const worker = cluster.fork()
  worker.on('exit', (code, signal) => {
    if (signal) {
      console.log(`el trabajador fue eliminado por la señal: ${signal}`)
    } else if (code !== 0) {
      console.log(`el trabajador salió con el código de error: ${code}`)
    } else {
      console.log('¡trabajador exitoso!')
    }
  })
}

Evento: 'listening'

Añadido en: v0.7.0

Similar al evento cluster.on('listening'), pero específico para este trabajador.

js
cluster.fork().on('listening', address => {
  // El trabajador está escuchando
})
js
cluster.fork().on('listening', address => {
  // El trabajador está escuchando
})

No se emite en el trabajador.

Evento: 'message'

Añadido en: v0.7.0

Similar al evento 'message' de cluster, pero específico para este trabajador.

Dentro de un trabajador, también se puede usar process.on('message').

Ver process evento: 'message'.

Aquí hay un ejemplo usando el sistema de mensajes. Mantiene un contador en el proceso principal del número de solicitudes HTTP recibidas por los trabajadores:

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

if (cluster.isPrimary) {
  // Realizar un seguimiento de las solicitudes http
  let numReqs = 0
  setInterval(() => {
    console.log(`numReqs = ${numReqs}`)
  }, 1000)

  // Contar solicitudes
  function messageHandler(msg) {
    if (msg.cmd && msg.cmd === 'notifyRequest') {
      numReqs += 1
    }
  }

  // Iniciar trabajadores y escuchar mensajes que contengan 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 {
  // Los procesos de trabajo tienen un servidor http.
  http
    .Server((req, res) => {
      res.writeHead(200)
      res.end('hello world\n')

      // Notificar al principal sobre la solicitud
      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) {
  // Realizar un seguimiento de las solicitudes http
  let numReqs = 0
  setInterval(() => {
    console.log(`numReqs = ${numReqs}`)
  }, 1000)

  // Contar solicitudes
  function messageHandler(msg) {
    if (msg.cmd && msg.cmd === 'notifyRequest') {
      numReqs += 1
    }
  }

  // Iniciar trabajadores y escuchar mensajes que contengan notifyRequest
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork()
  }

  for (const id in cluster.workers) {
    cluster.workers[id].on('message', messageHandler)
  }
} else {
  // Los procesos de trabajo tienen un servidor http.
  http
    .Server((req, res) => {
      res.writeHead(200)
      res.end('hello world\n')

      // Notificar al principal sobre la solicitud
      process.send({ cmd: 'notifyRequest' })
    })
    .listen(8000)
}

Evento: 'online'

Añadido en: v0.7.0

Similar al evento cluster.on('online'), pero específico para este trabajador.

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

No se emite en el trabajador.

worker.disconnect()

[Historial]

VersiónCambios
v7.3.0Este método ahora devuelve una referencia a worker.
v0.7.7Añadido en: v0.7.7

En un trabajador, esta función cerrará todos los servidores, esperará el evento 'close' en esos servidores y luego desconectará el canal IPC.

En el principal, se envía un mensaje interno al trabajador que hace que llame a .disconnect() sobre sí mismo.

Provoca que se establezca .exitedAfterDisconnect.

Después de cerrar un servidor, este ya no aceptará nuevas conexiones, pero las conexiones pueden ser aceptadas por cualquier otro trabajador en escucha. Se permitirá que las conexiones existentes se cierren como de costumbre. Cuando ya no existan más conexiones, ver server.close(), el canal IPC al trabajador se cerrará permitiendo que muera correctamente.

Lo anterior se aplica solo a las conexiones del servidor, las conexiones del cliente no se cierran automáticamente por los trabajadores, y la desconexión no espera a que se cierren antes de salir.

En un trabajador, existe process.disconnect, pero no es esta función; es disconnect().

Debido a que las conexiones de servidor de larga duración pueden bloquear la desconexión de los trabajadores, puede ser útil enviar un mensaje, para que se puedan tomar acciones específicas de la aplicación para cerrarlas. También puede ser útil implementar un tiempo de espera, matando a un trabajador si el evento 'disconnect' no se ha emitido después de un tiempo.

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 => {
    // Las conexiones nunca terminan
  })

  server.listen(8000)

  process.on('message', msg => {
    if (msg === 'shutdown') {
      // Iniciar el cierre correcto de cualquier conexión al servidor
    }
  })
}

worker.exitedAfterDisconnect

Añadido en: v6.0.0

Esta propiedad es true si el worker se cerró debido a .disconnect(). Si el worker se cerró de cualquier otra manera, es false. Si el worker no se ha cerrado, es undefined.

El booleano worker.exitedAfterDisconnect permite distinguir entre una salida voluntaria y accidental, el principal puede optar por no volver a generar un worker basándose en este valor.

js
cluster.on('exit', (worker, code, signal) => {
  if (worker.exitedAfterDisconnect === true) {
    console.log('Oh, fue voluntario – no hay de qué preocuparse')
  }
})

// matar worker
worker.kill()

worker.id

Añadido en: v0.8.0

A cada nuevo worker se le asigna su propio ID único, este ID se almacena en id.

Mientras un worker está activo, esta es la clave que lo indexa en cluster.workers.

worker.isConnected()

Añadido en: v0.11.14

Esta función devuelve true si el worker está conectado a su principal a través de su canal IPC, false en caso contrario. Un worker se conecta a su principal después de haber sido creado. Se desconecta después de que se emita el evento 'disconnect'.

worker.isDead()

Añadido en: v0.11.14

Esta función devuelve true si el proceso del worker ha terminado (ya sea por salida o por señal). De lo contrario, devuelve 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(`Principal ${process.pid} está en ejecución`)

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

  cluster.on('fork', worker => {
    console.log('worker is dead:', worker.isDead())
  })

  cluster.on('exit', (worker, code, signal) => {
    console.log('worker is dead:', worker.isDead())
  })
} else {
  // Los workers pueden compartir cualquier conexión TCP. En este caso, es un servidor HTTP.
  http
    .createServer((req, res) => {
      res.writeHead(200)
      res.end(`Proceso actual\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(`Principal ${process.pid} está en ejecución`)

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

  cluster.on('fork', worker => {
    console.log('worker is dead:', worker.isDead())
  })

  cluster.on('exit', (worker, code, signal) => {
    console.log('worker is dead:', worker.isDead())
  })
} else {
  // Los workers pueden compartir cualquier conexión TCP. En este caso, es un servidor HTTP.
  http
    .createServer((req, res) => {
      res.writeHead(200)
      res.end(`Proceso actual\n ${process.pid}`)
      process.kill(process.pid)
    })
    .listen(8000)
}

worker.kill([signal])

Añadido en: v0.9.12

  • signal <string> Nombre de la señal de muerte que se enviará al proceso worker. Predeterminado: 'SIGTERM'

Esta función matará al worker. En el worker principal, lo hace desconectando el worker.process, y una vez desconectado, matándolo con signal. En el worker, lo hace matando el proceso con signal.

La función kill() mata el proceso worker sin esperar una desconexión suave, tiene el mismo comportamiento que worker.process.kill().

Este método tiene el alias worker.destroy() por compatibilidad con versiones anteriores.

En un worker, existe process.kill(), pero no es esta función; es kill().

worker.process

Añadido en: v0.7.0

Todos los workers se crean usando child_process.fork(), el objeto devuelto por esta función se almacena como .process. En un worker, se almacena el process global.

Ver: Módulo Child Process.

Los workers llamarán a process.exit(0) si se produce el evento 'disconnect' en process y .exitedAfterDisconnect no es true. Esto protege contra desconexiones accidentales.

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

[Historial]

VersiónCambios
v4.0.0Ahora se admite el parámetro callback.
v0.7.0Añadido en: v0.7.0
  • message <Object>

  • sendHandle <Handle>

  • options <Object> El argumento options, si está presente, es un objeto que se utiliza para parametrizar el envío de ciertos tipos de manejadores. options admite las siguientes propiedades:

    • keepOpen <boolean> Un valor que se puede utilizar al pasar instancias de net.Socket. Cuando es true, el socket se mantiene abierto en el proceso de envío. Predeterminado: false.
  • callback <Function>

  • Devuelve: <boolean>

Envía un mensaje a un trabajador o principal, opcionalmente con un manejador.

En el principal, esto envía un mensaje a un trabajador específico. Es idéntico a ChildProcess.send().

En un trabajador, esto envía un mensaje al principal. Es idéntico a process.send().

Este ejemplo hará eco de todos los mensajes del principal:

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

Evento: 'disconnect'

Añadido en: v0.7.9

Emitido después de que el canal IPC del trabajador se haya desconectado. Esto puede ocurrir cuando un trabajador sale correctamente, es eliminado o se desconecta manualmente (como con worker.disconnect()).

Puede haber un retraso entre los eventos 'disconnect' y 'exit'. Estos eventos se pueden usar para detectar si el proceso está atascado en una limpieza o si hay conexiones de larga duración.

js
cluster.on('disconnect', worker => {
  console.log(`El trabajador #${worker.id} se ha desconectado`)
})

Evento: 'exit'

Añadido en: v0.7.9

  • worker <cluster.Worker>
  • code <number> El código de salida, si salió normalmente.
  • signal <string> El nombre de la señal (por ejemplo, 'SIGHUP') que provocó que el proceso fuera eliminado.

Cuando alguno de los trabajadores muere, el módulo cluster emitirá el evento 'exit'.

Esto se puede usar para reiniciar el trabajador volviendo a llamar a .fork().

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

Ver el evento child_process event: 'exit'.

Evento: 'fork'

Añadido en: v0.7.0

Cuando se bifurca un nuevo trabajador, el módulo cluster emitirá un evento 'fork'. Esto se puede utilizar para registrar la actividad del trabajador y crear un tiempo de espera personalizado.

js
const timeouts = []
function errorMsg() {
  console.error('Algo debe estar mal con la conexión...')
}

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'

Añadido en: v0.7.0

Después de llamar a listen() desde un trabajador, cuando se emite el evento 'listening' en el servidor, también se emitirá un evento 'listening' en cluster en el principal.

El controlador de eventos se ejecuta con dos argumentos, el worker contiene el objeto trabajador y el objeto address contiene las siguientes propiedades de conexión: address, port, y addressType. Esto es muy útil si el trabajador está escuchando en más de una dirección.

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

El addressType es uno de:

  • 4 (TCPv4)
  • 6 (TCPv6)
  • -1 (Socket de dominio Unix)
  • 'udp4' o 'udp6' (UDPv4 o UDPv6)

Evento: 'message'

[Historial]

VersiónCambios
v6.0.0Ahora se pasa el parámetro worker; vea los detalles a continuación.
v2.5.0Añadido en: v2.5.0

Emitido cuando el principal del clúster recibe un mensaje de cualquier trabajador.

Ver child_process evento: 'message'.

Evento: 'online'

Añadido en: v0.7.0

Después de bifurcar un nuevo trabajador, el trabajador debe responder con un mensaje en línea. Cuando el principal recibe un mensaje en línea, emitirá este evento. La diferencia entre 'fork' y 'online' es que fork se emite cuando el principal bifurca un trabajador, y 'online' se emite cuando el trabajador se está ejecutando.

js
cluster.on('online', worker => {
  console.log('¡Genial, el trabajador respondió después de ser bifurcado!')
})

Evento: 'setup'

Añadido en: v0.7.1

Emitido cada vez que se llama a .setupPrimary().

El objeto settings es el objeto cluster.settings en el momento en que se llamó a .setupPrimary() y solo es orientativo, ya que se pueden realizar varias llamadas a .setupPrimary() en un solo tick.

Si la precisión es importante, utilice cluster.settings.

cluster.disconnect([callback])

Añadido en: v0.7.7

  • callback <Function> Llamado cuando todos los workers están desconectados y los manejadores están cerrados.

Llama a .disconnect() en cada worker en cluster.workers.

Cuando estén desconectados, todos los manejadores internos se cerrarán, permitiendo que el proceso principal muera correctamente si no hay otro evento esperando.

El método toma un argumento de devolución de llamada opcional que se llamará cuando termine.

Esto solo se puede llamar desde el proceso principal.

cluster.fork([env])

Añadido en: v0.6.0

Genera un nuevo proceso trabajador.

Esto solo se puede llamar desde el proceso principal.

cluster.isMaster

Añadido en: v0.8.1

Obsoleto desde: v16.0.0

[Estable: 0 - Obsoleto]

Estable: 0 Estabilidad: 0 - Obsoleto

Alias obsoleto para cluster.isPrimary.

cluster.isPrimary

Añadido en: v16.0.0

Verdadero si el proceso es principal. Esto se determina mediante process.env.NODE_UNIQUE_ID. Si process.env.NODE_UNIQUE_ID está indefinido, entonces isPrimary es true.

cluster.isWorker

Añadido en: v0.6.0

Verdadero si el proceso no es principal (es la negación de cluster.isPrimary).

cluster.schedulingPolicy

Añadido en: v0.11.2

La política de programación, ya sea cluster.SCHED_RR para round-robin o cluster.SCHED_NONE para dejarlo al sistema operativo. Esta es una configuración global y se congela efectivamente una vez que se genera el primer trabajador, o se llama a .setupPrimary(), lo que ocurra primero.

SCHED_RR es el valor predeterminado en todos los sistemas operativos excepto Windows. Windows cambiará a SCHED_RR una vez que libuv pueda distribuir eficazmente los manejadores IOCP sin incurrir en una gran pérdida de rendimiento.

cluster.schedulingPolicy también se puede configurar a través de la variable de entorno NODE_CLUSTER_SCHED_POLICY. Los valores válidos son 'rr' y 'none'.

cluster.settings

[Historial]

VersiónCambios
v13.2.0, v12.16.0Ahora se admite la opción serialization.
v9.5.0Ahora se admite la opción cwd.
v9.4.0Ahora se admite la opción windowsHide.
v8.2.0Ahora se admite la opción inspectPort.
v6.4.0Ahora se admite la opción stdio.
v0.7.1Añadido en: v0.7.1
  • <Objeto>
    • execArgv <string[]> Lista de argumentos de cadena pasados al ejecutable de Node.js. Predeterminado: process.execArgv.
    • exec <string> Ruta de archivo al archivo de trabajador. Predeterminado: process.argv[1].
    • args <string[]> Argumentos de cadena pasados al trabajador. Predeterminado: process.argv.slice(2).
    • cwd <string> Directorio de trabajo actual del proceso de trabajador. Predeterminado: undefined (hereda del proceso padre).
    • serialization <string> Especifica el tipo de serialización utilizada para enviar mensajes entre procesos. Los valores posibles son 'json' y 'advanced'. Consulte Serialización avanzada para child_process para obtener más detalles. Predeterminado: false.
    • silent <boolean> Si se debe o no enviar la salida a la entrada/salida estándar del padre. Predeterminado: false.
    • stdio <Array> Configura la entrada/salida estándar de los procesos bifurcados. Debido a que el módulo de clúster depende de IPC para funcionar, esta configuración debe contener una entrada 'ipc'. Cuando se proporciona esta opción, anula silent. Consulte child_process.spawn() y su parámetro stdio.
    • uid <number> Establece la identidad de usuario del proceso. (Consulte setuid(2).)
    • gid <number> Establece la identidad de grupo del proceso. (Consulte setgid(2).)
    • inspectPort <number> | <Function> Establece el puerto del inspector del trabajador. Esto puede ser un número o una función que no toma argumentos y devuelve un número. De forma predeterminada, cada trabajador obtiene su propio puerto, incrementado desde el process.debugPort principal.
    • windowsHide <boolean> Oculta la ventana de consola de los procesos bifurcados que normalmente se crearían en sistemas Windows. Predeterminado: false.

Después de llamar a .setupPrimary() (o .fork()), este objeto de configuración contendrá la configuración, incluidos los valores predeterminados.

Este objeto no está destinado a ser modificado o establecido manualmente.

cluster.setupMaster([settings])

[Historial]

VersiónCambios
v16.0.0Obsoleto desde: v16.0.0
v6.4.0La opción stdio ahora es compatible.
v0.7.1Añadido en: v0.7.1

[Estable: 0 - Obsoleto]

Estable: 0 Estabilidad: 0 - Obsoleto

Alias obsoleto para .setupPrimary().

cluster.setupPrimary([settings])

Añadido en: v16.0.0

setupPrimary se utiliza para cambiar el comportamiento predeterminado de 'fork'. Una vez llamado, la configuración estará presente en cluster.settings.

Cualquier cambio en la configuración solo afecta a las llamadas futuras a .fork() y no tiene ningún efecto en los trabajadores que ya se están ejecutando.

El único atributo de un trabajador que no se puede establecer a través de .setupPrimary() es el env pasado a .fork().

Los valores predeterminados anteriores se aplican solo a la primera llamada; los valores predeterminados para las llamadas posteriores son los valores actuales en el momento en que se llama a cluster.setupPrimary().

js
import cluster from 'node:cluster'

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

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

Esto solo se puede llamar desde el proceso principal.

cluster.worker

Añadido en: v0.7.0

Una referencia al objeto worker actual. No está disponible en el proceso principal.

js
import cluster from 'node:cluster'

if (cluster.isPrimary) {
  console.log('Soy el principal')
  cluster.fork()
  cluster.fork()
} else if (cluster.isWorker) {
  console.log(`Soy el worker #${cluster.worker.id}`)
}
js
const cluster = require('node:cluster')

if (cluster.isPrimary) {
  console.log('Soy el principal')
  cluster.fork()
  cluster.fork()
} else if (cluster.isWorker) {
  console.log(`Soy el worker #${cluster.worker.id}`)
}

cluster.workers

Añadido en: v0.7.0

Un hash que almacena los objetos worker activos, con clave en el campo id. Esto facilita el recorrido por todos los workers. Solo está disponible en el proceso principal.

Un worker se elimina de cluster.workers después de que el worker se haya desconectado y haya salido. El orden entre estos dos eventos no se puede determinar de antemano. Sin embargo, se garantiza que la eliminación de la lista cluster.workers ocurre antes de que se emita el último evento 'disconnect' o 'exit'.

js
import cluster from 'node:cluster'

for (const worker of Object.values(cluster.workers)) {
  worker.send('gran anuncio a todos los workers')
}
js
const cluster = require('node:cluster')

for (const worker of Object.values(cluster.workers)) {
  worker.send('gran anuncio a todos los workers')
}