Skip to content

العناقيد

[مستقر: 2 - مستقر]

مستقر: 2 استقرار: 2 - مستقر

كود المصدر: lib/cluster.js

يمكن استخدام عناقيد عمليات Node.js لتشغيل مثيلات متعددة من Node.js يمكنها توزيع أحمال العمل بين خيوط تطبيقها. عندما لا تكون هناك حاجة لعزل العملية، استخدم وحدة worker_threads بدلاً من ذلك، والتي تسمح بتشغيل خيوط تطبيق متعددة داخل مثيل Node.js واحد.

تسمح وحدة العناقيد بإنشاء عمليات فرعية بسهولة تشترك جميعها في منافذ الخادم.

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(`الأساسي ${process.pid} قيد التشغيل`)

  // إنشاء عمال فرعيين.
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork()
  }

  cluster.on('exit', (worker, code, signal) => {
    console.log(`العامل ${worker.process.pid} توقف`)
  })
} else {
  // يمكن للعمال مشاركة أي اتصال TCP
  // في هذه الحالة هو خادم HTTP
  http
    .createServer((req, res) => {
      res.writeHead(200)
      res.end('hello world\n')
    })
    .listen(8000)

  console.log(`العامل ${process.pid} بدأ`)
}
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(`الأساسي ${process.pid} قيد التشغيل`)

  // إنشاء عمال فرعيين.
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork()
  }

  cluster.on('exit', (worker, code, signal) => {
    console.log(`العامل ${worker.process.pid} توقف`)
  })
} else {
  // يمكن للعمال مشاركة أي اتصال TCP
  // في هذه الحالة هو خادم HTTP
  http
    .createServer((req, res) => {
      res.writeHead(200)
      res.end('hello world\n')
    })
    .listen(8000)

  console.log(`العامل ${process.pid} بدأ`)
}

سيعمل تشغيل Node.js الآن على مشاركة المنفذ 8000 بين العمال:

bash
$ node server.js
الأساسي 3596 قيد التشغيل
العامل 4324 بدأ
العامل 4520 بدأ
العامل 6056 بدأ
العامل 5644 بدأ

في Windows، لا يزال من غير الممكن إعداد خادم أنابيب مسجل في عامل.

كيف يعمل

يتم إنشاء عمليات العامل باستخدام طريقة child_process.fork()، بحيث يمكنها التواصل مع العملية الرئيسية عبر IPC وتمرير مقابض الخادم ذهابًا وإيابًا.

يدعم وحدة cluster طريقتين لتوزيع الاتصالات الواردة.

الأولى (والافتراضية على جميع الأنظمة الأساسية باستثناء Windows) هي نهج الدوران الدائري، حيث تستمع العملية الرئيسية على منفذ، وتقبل اتصالات جديدة وتوزعها عبر العمال بطريقة الدوران الدائري، مع بعض الذكاء المدمج لتجنب تحميل عملية عامل.

النهج الثاني هو أن تقوم العملية الرئيسية بإنشاء مقبس الاستماع وإرساله إلى العمال المهتمين. ثم يقبل العمال الاتصالات الواردة مباشرة.

يجب أن يوفر النهج الثاني، من الناحية النظرية، أفضل أداء. ومع ذلك، في الممارسة العملية، يميل التوزيع إلى أن يكون غير متوازن للغاية بسبب تقلبات مُجدول نظام التشغيل. وقد لوحظت أحمال حيث انتهى أكثر من 70٪ من جميع الاتصالات في عمليتين فقط، من إجمالي ثمانية.

نظرًا لأن server.listen() ينقل معظم العمل إلى العملية الرئيسية، فهناك ثلاث حالات يختلف فيها السلوك بين عملية Node.js العادية وعامل cluster:

لا توفر Node.js منطق التوجيه. لذلك من المهم تصميم تطبيق بحيث لا يعتمد بشكل كبير على كائنات البيانات الموجودة في الذاكرة للأشياء مثل الجلسات وتسجيل الدخول.

بما أن العمال جميعهم عمليات منفصلة، يمكن قتلهم أو إعادة إنشائهم حسب احتياجات البرنامج، دون التأثير على العمال الآخرين. طالما أن هناك بعض العمال لا يزالون على قيد الحياة، سيستمر الخادم في قبول الاتصالات. إذا لم يكن هناك عمال على قيد الحياة، فسيتم إسقاط الاتصالات الحالية ورفض الاتصالات الجديدة. ومع ذلك، لا تدير Node.js عدد العمال تلقائيًا. تقع مسؤولية إدارة مجموعة العمال على عاتق التطبيق بناءً على احتياجاته الخاصة.

على الرغم من أن الحالة الرئيسية لاستخدام وحدة node:cluster هي الشبكات، إلا أنه يمكن أيضًا استخدامها لحالات استخدام أخرى تتطلب عمليات عامل.

الصنف: Worker

أضيف في: v0.7.0

يحتوي كائن Worker على جميع المعلومات والطرق العامة المتعلقة بالعامل. يمكن الحصول عليه بشكل أساسي باستخدام cluster.workers. وفي عامل، يمكن الحصول عليه باستخدام cluster.worker.

الحدث: 'disconnect'

أضيف في: v0.7.7

يشبه حدث cluster.on('disconnect')، ولكنه خاص بهذا العامل.

js
cluster.fork().on('disconnect', () => {
  // انفصل العامل
})

الحدث: 'error'

أضيف في: v0.7.3

هذا الحدث هو نفسه الحدث الذي يوفره child_process.fork().

ضمن عامل، يمكن أيضًا استخدام process.on('error').

الحدث: 'exit'

أضيف في: v0.11.2

  • code <number> رمز الخروج، إذا خرج بشكل طبيعي.
  • signal <string> اسم الإشارة (مثل 'SIGHUP') التي تسببت في قتل العملية.

يشبه حدث cluster.on('exit')، ولكنه خاص بهذا العامل.

js
import cluster from 'node:cluster'

if (cluster.isPrimary) {
  const worker = cluster.fork()
  worker.on('exit', (code, signal) => {
    if (signal) {
      console.log(`تم قتل العامل بإشارة: ${signal}`)
    } else if (code !== 0) {
      console.log(`خرج العامل برمز خطأ: ${code}`)
    } else {
      console.log('نجاح العامل!')
    }
  })
}
js
const cluster = require('node:cluster')

if (cluster.isPrimary) {
  const worker = cluster.fork()
  worker.on('exit', (code, signal) => {
    if (signal) {
      console.log(`تم قتل العامل بإشارة: ${signal}`)
    } else if (code !== 0) {
      console.log(`خرج العامل برمز خطأ: ${code}`)
    } else {
      console.log('نجاح العامل!')
    }
  })
}

الحدث: 'listening'

أضيف في: v0.7.0

يشبه حدث cluster.on('listening')، ولكنه خاص بهذا العامل.

js
cluster.fork().on('listening', address => {
  // يستمع العامل
})
js
cluster.fork().on('listening', address => {
  // يستمع العامل
})

لا يتم إصداره في العامل.

حدث: 'message'

مضاف في: v0.7.0

مشابه لحدث 'message' الخاص بـ cluster، ولكنه خاص بهذا العامل.

ضمن عامل، يمكن أيضًا استخدام process.on('message').

راجع process حدث: 'message'.

فيما يلي مثال على استخدام نظام الرسائل. يحافظ على عدد في العملية الرئيسية لعدد طلبات HTTP التي استقبلها العمال:

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

if (cluster.isPrimary) {
  // تتبع طلبات http
  let numReqs = 0
  setInterval(() => {
    console.log(`numReqs = ${numReqs}`)
  }, 1000)

  // عد الطلبات
  function messageHandler(msg) {
    if (msg.cmd && msg.cmd === 'notifyRequest') {
      numReqs += 1
    }
  }

  // بدء العمال والاستماع للرسائل التي تحتوي على 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 {
  // تمتلك عمليات العامل خادم http.
  http
    .Server((req, res) => {
      res.writeHead(200)
      res.end('hello world\n')

      // إبلاغ العملية الرئيسية بالطلب
      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) {
  // تتبع طلبات http
  let numReqs = 0
  setInterval(() => {
    console.log(`numReqs = ${numReqs}`)
  }, 1000)

  // عد الطلبات
  function messageHandler(msg) {
    if (msg.cmd && msg.cmd === 'notifyRequest') {
      numReqs += 1
    }
  }

  // بدء العمال والاستماع للرسائل التي تحتوي على notifyRequest
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork()
  }

  for (const id in cluster.workers) {
    cluster.workers[id].on('message', messageHandler)
  }
} else {
  // تمتلك عمليات العامل خادم http.
  http
    .Server((req, res) => {
      res.writeHead(200)
      res.end('hello world\n')

      // إبلاغ العملية الرئيسية بالطلب
      process.send({ cmd: 'notifyRequest' })
    })
    .listen(8000)
}

حدث: 'online'

مضاف في: v0.7.0

يشبه حدث cluster.on('online')، ولكنه خاص بهذا العامل.

js
cluster.fork().on('online', () => {
  // العامل متصل بالشبكة
})

لا يتم إصداره في العامل.

worker.disconnect()

[السجل]

الإصدارالتغييرات
v7.3.0هذه الطريقة تُعيد الآن مرجعًا إلى worker.
v0.7.7مضاف في: v0.7.7

في عامل، ستقوم هذه الدالة بإغلاق جميع الخوادم، والانتظار لحدث 'close' على تلك الخوادم، ثم فصل قناة IPC.

في العامل الرئيسي، يتم إرسال رسالة داخلية إلى العامل مما يتسبب في استدعاء .disconnect() على نفسه.

يؤدي إلى تعيين .exitedAfterDisconnect.

بعد إغلاق الخادم، لن يقبل المزيد من الاتصالات، ولكن قد يتم قبول الاتصالات بواسطة أي عامل استماع آخر. سيتم السماح للاتصالات الحالية بالإغلاق كالمعتاد. عندما لا توجد المزيد من الاتصالات، انظر server.close()، ستغلق قناة IPC إلى العامل مما يسمح له بالموت بشكل أنيق.

ينطبق ما سبق فقط على اتصالات الخادم، ولا يتم إغلاق اتصالات العميل تلقائيًا بواسطة العمال، ولا ينتظر الانفصال إغلاقها قبل الخروج.

في عامل، يوجد process.disconnect، ولكنه ليس هذه الدالة؛ بل هي disconnect().

بسبب أن اتصالات خادم طويلة الأمد قد تمنع العمال من الانفصال، فقد يكون من المفيد إرسال رسالة، حتى يمكن اتخاذ إجراءات محددة بالتطبيق لإغلاقها. قد يكون من المفيد أيضًا تنفيذ مهلة زمنية، وقتل عامل إذا لم يتم إصدار حدث 'disconnect' بعد مرور بعض الوقت.

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 => {
    // الاتصالات لا تنتهي أبدًا
  })

  server.listen(8000)

  process.on('message', msg => {
    if (msg === 'shutdown') {
      // بدء الإغلاق الأنيق لأي اتصالات بالخادم
    }
  })
}

worker.exitedAfterDisconnect

تم الإضافة في: v6.0.0

هذه الخاصية تساوي true إذا خرج عامل التشغيل بسبب .disconnect(). إذا خرج عامل التشغيل بأي طريقة أخرى، فسيكون false. إذا لم يخرج عامل التشغيل، فسيكون undefined.

يسمح المنطق البوولي worker.exitedAfterDisconnect بالتمييز بين الخروج الطوعي والصدفي، وقد يختار الرئيسي عدم إعادة تشغيل عامل بناءً على هذه القيمة.

js
cluster.on('exit', (worker, code, signal) => {
  if (worker.exitedAfterDisconnect === true) {
    console.log('آه، كان مجرد طوعي - لا داعي للقلق')
  }
})

// إيقاف تشغيل عامل التشغيل
worker.kill()

worker.id

تم الإضافة في: v0.8.0

يتم منح كل عامل تشغيل جديد معرف فريد خاص به، ويتم تخزين هذا المعرف في id.

بينما عامل التشغيل حي، هذا هو المفتاح الذي يفهرسه في cluster.workers.

worker.isConnected()

تم الإضافة في: v0.11.14

ترجع هذه الدالة true إذا كان عامل التشغيل متصلاً برئيسه عبر قناة IPC الخاصة به، false بخلاف ذلك. يكون عامل التشغيل متصلاً برئيسه بعد إنشائه. يتم فصله بعد إرسال حدث 'disconnect'.

worker.isDead()

تم الإضافة في: v0.11.14

ترجع هذه الدالة true إذا تم إنهاء عملية عامل التشغيل (إما بسبب الخروج أو الإشارة). خلاف ذلك، سترجع 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(`الرئيسي ${process.pid} قيد التشغيل`)

  // إنشاء عمال فرعيين.
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork()
  }

  cluster.on('fork', worker => {
    console.log('عامل التشغيل ميت:', worker.isDead())
  })

  cluster.on('exit', (worker, code, signal) => {
    console.log('عامل التشغيل ميت:', worker.isDead())
  })
} else {
  // يمكن للعمال مشاركة أي اتصال TCP. في هذه الحالة، هو خادم HTTP.
  http
    .createServer((req, res) => {
      res.writeHead(200)
      res.end(`العملية الحالية\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(`الرئيسي ${process.pid} قيد التشغيل`)

  // إنشاء عمال فرعيين.
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork()
  }

  cluster.on('fork', worker => {
    console.log('عامل التشغيل ميت:', worker.isDead())
  })

  cluster.on('exit', (worker, code, signal) => {
    console.log('عامل التشغيل ميت:', worker.isDead())
  })
} else {
  // يمكن للعمال مشاركة أي اتصال TCP. في هذه الحالة، هو خادم HTTP.
  http
    .createServer((req, res) => {
      res.writeHead(200)
      res.end(`العملية الحالية\n ${process.pid}`)
      process.kill(process.pid)
    })
    .listen(8000)
}

worker.kill([signal])

تم الإضافة في: v0.9.12

  • signal <string> اسم إشارة الإيقاف التي سيتم إرسالها إلى عملية عامل التشغيل. الافتراضي: 'SIGTERM'

ستقوم هذه الدالة بإنهاء عامل التشغيل. في عامل التشغيل الرئيسي، يقوم بذلك عن طريق فصل worker.process، وبمجرد الفصل، يتم الإيقاف باستخدام signal. في عامل التشغيل، يقوم بذلك عن طريق إنهاء العملية باستخدام signal.

تقوم دالة kill() بإنهاء عملية عامل التشغيل دون انتظار فصل سلس، ولها نفس سلوك worker.process.kill().

تمت تسمية هذه الطريقة باسم worker.destroy() للتوافق مع الإصدارات السابقة.

في عامل تشغيل، توجد process.kill(), لكنها ليست هذه الدالة؛ إنها kill().

worker.process

تم الإضافة في: v0.7.0

يتم إنشاء جميع عمال التشغيل باستخدام child_process.fork()، ويتم تخزين الكائن المُرجَع من هذه الدالة كـ.process. في عامل تشغيل، يتم تخزين process العام.

انظر: وحدة معالجة الطفل.

سيقوم عمال التشغيل باستدعاء process.exit(0) إذا حدث حدث 'disconnect' على process و .exitedAfterDisconnect ليس true. هذا يحمي من الانفصال العرضي.

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

[السجل]

الإصدارالتغييرات
v4.0.0تم دعم معامل callback الآن.
v0.7.0تم الإضافة في: v0.7.0
  • message <Object>

  • sendHandle <Handle>

  • options <Object> وسيطة options، إذا وُجدت، هي كائن يُستخدم لمعلمات إرسال أنواع معينة من المقابض. يدعم options الخصائص التالية:

    • keepOpen <boolean> قيمة يمكن استخدامها عند تمرير مثيلات net.Socket. عندما تكون true، يبقى المقبس مفتوحًا في عملية الإرسال. الافتراضي: false.
  • callback <Function>

  • الإرجاع: <boolean>

إرسال رسالة إلى عامل تشغيل أو رئيسي، اختياريًا مع مقبض.

في الرئيسي، هذا يرسل رسالة إلى عامل تشغيل محدد. إنه مطابق لـ ChildProcess.send().

في عامل تشغيل، هذا يرسل رسالة إلى الرئيسي. إنه مطابق لـ process.send().

سيعيد هذا المثال جميع الرسائل من الرئيسي:

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

حدث: 'disconnect'

تمت الإضافة في: v0.7.9

يتم إصداره بعد فصل قناة IPC للعامل. يمكن أن يحدث هذا عندما يخرج العامل بشكل طبيعي، أو يتم قتله، أو يتم فصله يدويًا (مثل استخدام worker.disconnect()).

قد يكون هناك تأخير بين حدثي 'disconnect' و 'exit' . يمكن استخدام هذه الأحداث للكشف عما إذا كانت العملية عالقة في عملية تنظيف أو ما إذا كانت هناك اتصالات طويلة الأمد.

js
cluster.on('disconnect', worker => {
  console.log(`العامل رقم ${worker.id} قد تم فصله`)
})

حدث: 'exit'

تمت الإضافة في: v0.7.9

  • worker <cluster.Worker>
  • code <number> رمز الخروج، إذا خرج بشكل طبيعي.
  • signal <string> اسم الإشارة (مثل 'SIGHUP') التي تسببت في قتل العملية.

عندما يموت أي من العمال، سيصدر وحدة النمط cluster حدث 'exit' .

يمكن استخدام هذا لإعادة تشغيل العامل عن طريق استدعاء .fork() مرة أخرى.

js
cluster.on('exit', (worker, code, signal) => {
  console.log('العامل %d مات (%s). إعادة التشغيل...', worker.process.pid, signal || code)
  cluster.fork()
})

انظر إلى حدث [child_process]: 'exit'](/ar/api/child_process#event-exit).

حدث: 'fork'

تمت الإضافة في: v0.7.0

عندما يتم إنشاء عامل جديد، ستصدر وحدة النمط cluster حدث 'fork' . يمكن استخدام هذا لتسجيل نشاط العامل، وإنشاء مهلة زمنية مخصصة.

js
const timeouts = []
function errorMsg() {
  console.error('يجب أن يكون هناك خطأ ما في الاتصال...')
}

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

الحدث: 'listening'

مضاف في: v0.7.0

بعد استدعاء listen() من عامل، عندما يتم إصدار حدث 'listening' على الخادم، سيتم أيضًا إصدار حدث 'listening' على cluster في العامل الرئيسي.

يتم تنفيذ مُعالِج الحدث مع وسيطين، يحتوي worker على كائن العامل، ويحتوي كائن address على خصائص الاتصال التالية: address، وport، وaddressType. هذا مفيد جدًا إذا كان العامل يستمع على أكثر من عنوان واحد.

js
cluster.on('listening', (worker, address) => {
  console.log(`العامل الآن متصل بـ ${address.address}:${address.port}`)
})

addressType هو أحد:

  • 4 (TCPv4)
  • 6 (TCPv6)
  • -1 (مقبس نطاق يونكس)
  • 'udp4' أو 'udp6' (UDPv4 أو UDPv6)

الحدث: 'message'

[السجل]

الإصدارالتغييرات
v6.0.0تم تمرير وسيط worker الآن؛ راجع التفاصيل أدناه.
v2.5.0مضاف في: v2.5.0

يُصدر عندما يستقبل العامل الرئيسي للعنقود رسالة من أي عامل.

انظر إلى حدث child_process: 'message'.

الحدث: 'online'

مضاف في: v0.7.0

بعد إنشاء عامل جديد، يجب أن يستجيب العامل برسالة اتصال. عندما يستقبل العامل الرئيسي رسالة اتصال، فإنه سيُصدر هذا الحدث. الفرق بين 'fork' و'online' هو أن fork يُصدر عندما يقوم العامل الرئيسي بإنشاء عامل، و'online' يُصدر عندما يكون العامل قيد التشغيل.

js
cluster.on('online', worker => {
  console.log('رائع، استجاب العامل بعد إنشائه')
})

الحدث: 'setup'

مضاف في: v0.7.1

يُصدر في كل مرة يتم فيها استدعاء .setupPrimary().

كائن settings هو كائن cluster.settings في وقت استدعاء .setupPrimary() وهو للاستشارة فقط، نظرًا لإمكانية إجراء العديد من المكالمات لـ .setupPrimary() في دورة واحدة.

إذا كانت الدقة مهمة، فاستخدم cluster.settings.

cluster.disconnect([callback])

مضاف في: v0.7.7

  • callback <Function> يتم استدعاؤه عندما يتم فصل جميع العمال وإغلاق المقابض.

يقوم بالاتصال بـ .disconnect() على كل عامل في cluster.workers.

عندما يتم فصلهم، سيتم إغلاق جميع المقابض الداخلية، مما يسمح لعملية المُعالجة الأساسية بالموت بشكل جيد إذا لم يكن هناك حدث آخر في انتظار.

تأخذ هذه الطريقة وسيطة اختيارية لاستدعاء المُستدعى عند الانتهاء.

لا يمكن استدعاء هذا إلا من العملية الأساسية.

cluster.fork([env])

مضاف في: v0.6.0

  • env <Object> أزواج المفتاح/القيمة المراد إضافتها إلى بيئة عملية العامل.
  • الإرجاع: <cluster.Worker>

إنشاء عملية عامل جديدة.

لا يمكن استدعاء هذا إلا من العملية الأساسية.

cluster.isMaster

مضاف في: v0.8.1

مُهمل منذ: v16.0.0

[مستقر: 0 - مُهمل]

مستقر: 0 ثبات: 0 - مُهمل

اسم مُهمل لـ cluster.isPrimary.

cluster.isPrimary

مضاف في: v16.0.0

صحيح إذا كانت العملية أساسية. يتم تحديد هذا بواسطة process.env.NODE_UNIQUE_ID. إذا كان process.env.NODE_UNIQUE_ID غير مُعرّف، فإن isPrimary يكون true.

cluster.isWorker

مضاف في: v0.6.0

صواب إذا لم تكن العملية أساسية (إنها نفي cluster.isPrimary).

cluster.schedulingPolicy

مضاف في: v0.11.2

نهج الجدولة، إما cluster.SCHED_RR لـ دوري أو cluster.SCHED_NONE لتركه لنظام التشغيل. هذا إعداد عام ويتم تجميده بشكل فعال بمجرد ظهور أول عامل، أو استدعاء .setupPrimary()، أيهما يأتي أولاً.

SCHED_RR هو الإعداد الافتراضي على جميع أنظمة التشغيل باستثناء Windows. سيتغير Windows إلى SCHED_RR بمجرد تمكن libuv من توزيع مقابض IOCP بكفاءة دون تكبد خسارة كبيرة في الأداء.

يمكن أيضًا تعيين cluster.schedulingPolicy من خلال متغير البيئة NODE_CLUSTER_SCHED_POLICY. القيم الصالحة هي 'rr' و 'none'.

cluster.settings

[السجل]

الإصدارالتغييرات
v13.2.0، v12.16.0خيار serialization مدعوم الآن.
v9.5.0خيار cwd مدعوم الآن.
v9.4.0خيار windowsHide مدعوم الآن.
v8.2.0خيار inspectPort مدعوم الآن.
v6.4.0خيار stdio مدعوم الآن.
v0.7.1مضاف في: v0.7.1
  • <Object>
    • execArgv <string[]> قائمة بحجج السلسلة الممررة إلى ملف قابل للتنفيذ في Node.js. الافتراضي: process.execArgv.
    • exec <string> مسار الملف إلى ملف العامل. الافتراضي: process.argv[1].
    • args <string[]> حجج السلسلة الممررة إلى العامل. الافتراضي: process.argv.slice(2).
    • cwd <string> دليل العمل الحالي لعملية العامل. الافتراضي: undefined (يرث من عملية الأصل).
    • serialization <string> حدد نوع التسلسل المستخدم لإرسال الرسائل بين العمليات. القيم الممكنة هي 'json' و 'advanced'. راجع التسلسل المتقدم لـ child_process لمزيد من التفاصيل. الافتراضي: false.
    • silent <boolean> ما إذا كان سيتم إرسال الإخراج إلى stdio للوالد أم لا. الافتراضي: false.
    • stdio <Array> يُهيئ stdio للعمليات المتفرعة. نظرًا لأن وحدة cluster تعتمد على IPC للعمل، فيجب أن تحتوي هذه التهيئة على إدخال 'ipc'. عندما يتم توفير هذا الخيار، فإنه يتجاوز silent. راجع child_process.spawn()'s stdio.
    • uid <number> يحدد هوية المستخدم للعملية. (راجع setuid(2). )
    • gid <number> يحدد هوية المجموعة للعملية. (راجع setgid(2). )
    • inspectPort <number> | <Function> يحدد منفذ المفتش للعامل. يمكن أن يكون هذا رقمًا، أو دالة لا تأخذ أي حجج وتعيد رقمًا. بشكل افتراضي، يحصل كل عامل على منفذه الخاص، ويزداد من process.debugPort للوالد.
    • windowsHide <boolean> إخفاء نافذة وحدة التحكم لعمليات متفرعة سيتم إنشاؤها عادةً على أنظمة Windows. الافتراضي: false.

بعد استدعاء .setupPrimary() (أو .fork()) ، سيحتوي كائن الإعدادات هذا على الإعدادات، بما في ذلك القيم الافتراضية.

لم يُقصد من هذا الكائن أن يتم تغييره أو تعيينه يدويًا.

cluster.setupMaster([settings])

[السجل]

الإصدارالتغييرات
v16.0.0مُهمل منذ: v16.0.0
v6.4.0خيار stdio مدعوم الآن.
v0.7.1تمت الإضافة في: v0.7.1

[مستقر: 0 - مُهمل]

مستقر: 0 الثبات: 0 - مُهمل

اسم بديل مُهمل لـ .setupPrimary().

cluster.setupPrimary([settings])

تمت الإضافة في: v16.0.0

setupPrimary تُستخدم لتغيير سلوك "fork" الافتراضي. بمجرد استدعائها، ستكون الإعدادات موجودة في cluster.settings.

أي تغييرات في الإعدادات تؤثر فقط على المكالمات المستقبلية لـ .fork() وليس لها أي تأثير على العمال الذين يعملون بالفعل.

السمة الوحيدة للعامل التي لا يمكن تعيينها عبر .setupPrimary() هي env المُمرر إلى .fork().

تُطبق الإعدادات الافتراضية أعلاه على المكالمة الأولى فقط؛ الإعدادات الافتراضية للمكالمات اللاحقة هي القيم الحالية وقت استدعاء cluster.setupPrimary().

js
import cluster from 'node:cluster'

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

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

لا يمكن استدعاء هذا إلا من العملية الرئيسية.

cluster.worker

تمت الإضافة في: v0.7.0

مرجع لكائن العامل الحالي. غير متوفر في العملية الرئيسية.

js
import cluster from 'node:cluster'

if (cluster.isPrimary) {
  console.log('أنا العملية الرئيسية')
  cluster.fork()
  cluster.fork()
} else if (cluster.isWorker) {
  console.log(`أنا العامل رقم ${cluster.worker.id}`)
}
js
const cluster = require('node:cluster')

if (cluster.isPrimary) {
  console.log('أنا العملية الرئيسية')
  cluster.fork()
  cluster.fork()
} else if (cluster.isWorker) {
  console.log(`أنا العامل رقم ${cluster.worker.id}`)
}

cluster.workers

مضاف في: v0.7.0

هاش يخزن كائنات العامل النشطة، ومفتاحها هو حقل id. هذا يسهل التكرار عبر جميع العمال. وهو متوفر فقط في العملية الرئيسية.

يتم إزالة عامل من cluster.workers بعد فصل العامل وخروجه. لا يمكن تحديد الترتيب بين هذين الحدثين مسبقًا. ومع ذلك، من المضمون أن تتم الإزالة من قائمة cluster.workers قبل إصدار آخر حدث 'disconnect' أو 'exit'.

js
import cluster from 'node:cluster'

for (const worker of Object.values(cluster.workers)) {
  worker.send('big announcement to all workers')
}
js
const cluster = require('node:cluster')

for (const worker of Object.values(cluster.workers)) {
  worker.send('big announcement to all workers')
}