IlmHamroh
JavaScript Full-stack/24-qism. Node.js38/55-dars15 daqiqa
Mundarija (28)

Node.js cluster: ko'p yadroli masshtablash va Windows tuzog'i

Qisqacha: Bitta Node jarayoni JavaScript'ni bitta yadroda bajaradi. cluster moduli bir nechta Node jarayonini (ishchi) ochadi va ular bitta portni bo'lishadi — har biri o'z yadrosida. Kim qaysi ulanishni olishini taqsimlash siyosati hal qiladi. Kanon topilmasi: Windows'da sukut bo'yicha OS taqsimlaydi va 200 so'rovning hammasi bitta ishchiga tushdi. NODE_CLUSTER_SCHED_POLICY=rr bilan esa 50/50/50/50 bo'ldi. Bugun ko'pincha cluster o'rniga bir nechta konteyner ishlatiladi.

Bu darsda

  • cluster.fork() bilan ishchilar ochib, ular bitta portni qanday bo'lishishini tushuntira olasiz.
  • Round-robin va SCHED_NONE farqini va Windows'dagi topilmani bilasiz.
  • Yiqilgan ishchini qayta ishga tushirasiz va ishchi bilan xabar almashasiz.
  • Sticky session muammosini va uning yechimlarini tushuntirasiz.
  • cluster, PM2 va konteyner replikalari orasidan asos bilan tanlaysiz.

Oldin bilishingiz kerak: worker_threads, child_process, process obyekti, WebSocket va Server-Sent Events.

1. Nega bu kerak?

worker_threads darsida og'ir hisobni boshqa thread'ga chiqardik. Lekin server boshqa muammoga duch keladi: so'rovlar juda ko'p. Har biri yengil — bazadan o'qish, JSON qaytarish. Lekin sekundiga 5 000 ta. Bitta Node jarayoni ularning JavaScript qismini bitta yadroda bajaradi. Serverda esa 8 yoki 16 yadro bor, qolganlari bekor turadi.

Yechim — butun serverni bir necha nusxada ishga tushirish: har yadroga bittadan. Ammo ular bitta portni (masalan 3000) qanday bo'lishadi? Odatda bitta port — bitta dastur. cluster moduli shu masalani hal qiladi.

Hayotiy o'xshatish: bankda bitta kassa — navbat ko'chaga chiqib ketadi. Bank yana uchta kassa ochadi. Mijozlar baribir bitta eshikdan kiradi. Eshik oldida navbatchi turadi va har kirganni bo'sh kassaga yuboradi. cluster — o'sha navbatchi (asosiy jarayon) va kassalar (ishchilar). Bugungi asosiy savol: navbatchi mijozlarni adolatli taqsimlaydimi?

Diqqat: Bu darsda kichik HTTP server ishlatamiz: http.createServer((so'rov, javob) => javob.end("...")) — har so'rovga matn qaytaradi. HTTP serverlarni 25-qismda to'liq o'rganamiz. Hozir bitta qatorni bilish yetarli: u portni tinglaydi va har kelgan so'rovga javob beradi.

2. cluster qanday ishlaydi

2.1 Asosiy jarayon va ishchilar

cluster.fork() — joriy faylni yangi Node jarayoni sifatida yana ishga tushiradi. child_process darsidagi fork ga o'xshaydi, lekin ishchi bilan port bo'lishish ham qo'shiladi. Fayl qaysi rolda ekanini cluster.isPrimary aytadi:

flowchart TB
  M["Asosiy<br/>jarayon"] -->|fork| W1["Ishchi 1<br/>listen 3124"]
  M -->|fork| W2["Ishchi 2<br/>listen 3124"]
  M -->|fork| W3["Ishchi 3<br/>listen 3124"]
  K((Mijozlar)) --> M

Ishchilarning hammasi listen(3124) qiladi. Ular portni haqiqatan ochmaydi — ularning listen chaqiruvi asosiy jarayonga yo'naltiriladi va port bitta bo'lib qoladi. Ulanishni qaysi ishchi olishini esa taqsimlash siyosati hal qiladi.

worker_threads bilan farqi muhim:

worker_threads cluster
Nima thread — bitta jarayon ichida butun jarayon (alohida PID)
Xotira SharedArrayBuffer bilan bo'lishish mumkin umuman umumiy emas
Narx ~20 ms, bir necha MB to'liq Node jarayoni (~38 MB rss)
Vazifasi og'ir hisobni chiqarish ko'p so'rovni ko'p yadroga yoyish
Yiqilsa jarayon tirik qoladi faqat o'sha ishchi o'ladi

2.2 Ishchi bilan xabar va qayta ishga tushirish

Ishchi — alohida jarayon, u yiqilishi mumkin. Asosiy jarayon exit hodisasini tinglaydi va o'rniga yangisini ochadi. Xabar almashish — process.send() va message hodisasi. Bu blokda HTTP yo'q, faqat jarayonlar:

js
import cluster from "node:cluster";

if (cluster.isPrimary) {
  let qayta = 0;
  cluster.on("exit", (w, kod) => {
    console.log(`ishchi ${w.id} yiqildi (kod ${kod})`);
    if (qayta++ < 2) cluster.fork();
    else console.log("yetarli — qayta ishga tushirmaymiz");
  });
  cluster.on("message", (w, x) => console.log(`ishchi ${w.id}:`, x));
  cluster.fork();
} else {
  process.send("ishga tushdim");
  setTimeout(() => process.exit(1), 50);
}

Konsolda:

text
ishchi 1: ishga tushdim
ishchi 1 yiqildi (kod 1)
ishchi 2: ishga tushdim
ishchi 2 yiqildi (kod 1)
ishchi 3: ishga tushdim
ishchi 3 yiqildi (kod 1)
yetarli — qayta ishga tushirmaymiz

Har ishchi xabar yubordi va 50 ms dan keyin 1 kodi bilan chiqdi (xatoni taqlid qildik). Asosiy jarayon har safar yangisini ochdi. Ishchi raqami (w.id) o'sib boradi — bu yangi jarayon, eskisi qaytmaydi.

Real kodda qayta < 2 o'rniga boshqa himoya kerak bo'ladi: ishchi ishga tushishi bilanoq yiqilsa (masalan, .env da xato), cheksiz "fork — yiqilish — fork" aylanishi protsessorni yeb qo'yadi. Odatda vaqt oynasi ishlatiladi: "1 daqiqada 5 martadan ko'p yiqilsa — to'xta va xabar ber".

Tekshirib ko'ring: Ishchi 1 xotirasida let sanoq = 0 bor va har so'rovda u oshadi. Ishchi 2 bu sanoqni ko'radimi?

Javob

Yo'q. Har ishchi — alohida jarayon, o'z xotirasi bilan. Ikkalasida ham o'z sanoq i bor. Umumiy ma'lumot kerak bo'lsa, u jarayondan tashqarida turishi kerak: ma'lumotlar bazasi, Redis yoki asosiy jarayon orqali xabarlar. Bu cluster'ning eng muhim oqibati — «Sticky session» bo'limida unga qaytamiz.

3. Taqsimlash: round-robin va Windows topilmasi

3.1 Ikki siyosat

Node hujjatiga ko'ra ikki usul bor:

  • SCHED_RR (round-robin, navbatma-navbat) — asosiy jarayon ulanishni o'zi qabul qiladi va ishchilarga navbat bilan beradi: 1, 2, 3, 4, 1, 2… Linux va macOS'da sukut shu.
  • SCHED_NONE — ulanishni kim qabul qilishini operatsion tizim hal qiladi. Hujjatga ko'ra Windows'da sukut shu.

Hujjat SCHED_NONE haqida ogohlantiradi: OS "eng issiq" (yaqinda ishlagan) jarayonni afzal ko'rishi mumkin va yuk notekis bo'ladi. Kanon buni o'lchadi.

3.2 Kanon o'lchovi: 200 so'rov

4 ishchi, har biri javobda o'z PID'ini qaytaradi. Asosiy jarayon 200 ta so'rov yuboradi (connection: close — har so'rov yangi ulanish) va kim nechta olganini sanaydi (tajriba/t38-cluster.mjs):

js
import cluster from "node:cluster";
import http from "node:http";

if (cluster.isPrimary) {
  const ishchilar = Array.from({ length: 4 }, () => cluster.fork());
  await Promise.all(ishchilar.map(
    (w) => new Promise((r) => w.once("listening", r))));
  const sanoq = {};
  for (let i = 0; i < 200; i++) {
    const javob = await fetch("http://127.0.0.1:3124/", {
      headers: { connection: "close" },
    });
    const pid = await javob.text();
    sanoq[pid] = (sanoq[pid] ?? 0) + 1;
  }
  console.log("ishchilar bo'yicha:", Object.values(sanoq));
  for (const w of ishchilar) w.kill();
} else {
  http.createServer((_so, ja) => ja.end(String(process.pid)))
    .listen(3124, "127.0.0.1");
}

Blok kanon skriptidan telefon uchun qisqartirilgan: kanon qo'shimcha ravishda platforma va siyosat nomini chiqaradi va sonlarni tartiblaydi. Shuning uchun quyidagi qatorlar matni blokdagi console.log dan biroz farq qiladi, raqamlar esa aynan kanonniki.

Kanon natijasi (t38-cluster.txt, Node 24.21.0, Windows 11, i5-12500H). Ikkinchi qatordagi massivga qarang — unda nechta son bor:

text
platforma: win32 | schedulingPolicy: SCHED_NONE (OS taqsimlaydi)
200 so'rov (connection: close) pid bo'yicha: [ 200 ]

200 tasining hammasi bitta ishchiga tushdi. Qolgan uchta ishchi bitta ham so'rov olmadi. Ya'ni Windows'da sukut sozlamasi bilan cluster bu sinovda hech narsa bermadi: to'rt jarayon xotira oldi, ish esa bittasida.

Endi xuddi shu kodni round-robin bilan ishga tushirdik — muhit o'zgaruvchisi NODE_CLUSTER_SCHED_POLICY=rr (biz ishga tushirdik, o'sha mashina, ikki marta):

bash
NODE_CLUSTER_SCHED_POLICY=rr node cluster-sinov.mjs
text
win32 | SCHED_RR (round-robin)
200 so'rov ishchilar bo'yicha: [ 50, 50, 50, 50 ]
Windows: 200 so'rovning eng ko'p yuklangan ishchidagi ulushi
  • Sukut (SCHED_NONE)hammasi bitta ishchiga200 so'rov
  • NODE_CLUSTER_SCHED_POLICY=rr4 ishchiga teng50 so'rov

Manba: IlmHamroh o'lchovi, 2026-10-23: Node 24.21.0, Windows 11, i5-12500H, 4 ishchi (t38-cluster.txt + rr sinovi)

Bash'da O'ZGARUVCHI=qiymat buyruq — o'zgaruvchini faqat shu buyruq uchun berish (process obyekti darsidagi process.env). PowerShell'da: $env:NODE_CLUSTER_SCHED_POLICY = "rr"; node cluster-sinov.mjs. Kodda ham berish mumkin: cluster.schedulingPolicy = cluster.SCHED_RR — birinchi fork() dan oldin.

Linux'da biz sinamadik (kanon mashinasida WSL va Docker yo'q). Hujjatga ko'ra u yerda sukut — round-robin, ya'ni shu natija sozlamasiz chiqishi kerak. Halol qoida: cluster'ni ishlatadigan serverda taqsimotni o'zingiz o'lchang.

Diqqat: Internetdagi ko'p maqolalar "cluster yukni ishchilar orasida teng taqsimlaydi" deydi. Windows'dagi sukut sozlamasida bu rost emas — o'lchov buni ko'rsatdi.

3.3 Ulanish va so'rov — boshqa narsalar

Yana bir nozik joy: round-robin ulanishlarni taqsimlaydi, so'rovlarni emas. connection: close ni olib tashlasak, fetch ulanishni qayta ishlatadi (keep-alive — 25-qismda). Biz ishga tushirdik (rr bilan):

text
win32 | SCHED_RR (round-robin)
200 so'rov ishchilar bo'yicha: [ 100, 100 ]

200 so'rov atigi ikkita ulanishda ketdi — shuning uchun faqat ikki ishchi ish oldi. Haqiqiy saytda minglab mijoz bo'lgani uchun ulanishlar ko'p va taqsimot tekisroq bo'ladi. Lekin bitta "og'ir" mijoz (masalan, boshqa server sizga ko'p so'rov yuborsa) baribir bitta ishchiga yopishib qoladi.

Tekshirib ko'ring: Nega sinovda connection: close sarlavhasini qo'ydik?

Javob

Har so'rov yangi ulanish ochishi uchun. Taqsimlash ulanish darajasida bo'ladi: bitta ulanishdagi hamma so'rov o'sha ishchiga boradi. connection: close siz biz siyosatni emas, fetch ning ulanish hovuzini o'lchagan bo'lardik — natija [100, 100] bo'lgani shuni ko'rsatadi.

4. Sticky session muammosi

Ishchilar xotirani bo'lishmaydi. Bu ikki joyda og'riq beradi.

Xotiradagi sessiya. Foydalanuvchi tizimga kirdi — server uni Map da eslab qoldi. Bu 1-ishchining xotirasi. Keyingi so'rov 3-ishchiga tushdi — u foydalanuvchini tanimaydi: "qayta kiring". Sayt tasodifiy ravishda foydalanuvchini tizimdan chiqaradi.

WebSocket va uzun ulanishlar. WebSocket va SSE darsidagi ba'zi kutubxonalar (masalan, Socket.IO'ning eski polling rejimi) bir mijozning bir nechta so'rovi bitta ishchiga tushishini talab qiladi.

Sticky session ("yopishqoq sessiya") — bitta mijozni doim bitta ishchiga yuborish (odatda IP yoki cookie bo'yicha). U muammoni yashiradi, lekin yangi muammo keltiradi: ishchi yiqilsa, uning mijozlari baribir sessiyani yo'qotadi, yuk esa notekis bo'ladi. Node'ning cluster i sticky session'ni o'zi qilmaydi — uning uchun nginx (ip_hash) yoki maxsus paket kerak.

To'g'ri yechim — holatsiz (stateless) server: sessiya va umumiy ma'lumot jarayon ichida emas, tashqarida (baza, Redis — 26–27-qismlarda) saqlanadi. Shunda istalgan ishchi istalgan so'rovga javob bera oladi. Bu qoida cluster'ga ham, bir nechta serverga ham bir xil tegishli.

Ma'lumot Qayerda saqlanadi
Foydalanuvchi sessiyasi baza yoki Redis (yoki imzolangan cookie)
Kesh Redis yoki har ishchida alohida (ataylab)
Fayllar (yuklanganlar) disk yoki obyekt ombori, xotira emas
Hisoblagichlar, limitlar Redis

5. PM2 va konteyner replikalari

5.1 PM2 cluster mode

Qo'lda cluster.fork(), exit va qayta ishga tushirishni yozish o'rniga ko'p jamoalar PM2 dan foydalanadi — Node jarayonlari menejeri. Uning cluster rejimi ichkarida aynan Node'ning cluster modulini ishlatadi. Rasmiy hujjatdagi sozlama fayli (biz PM2'ni o'rnatmadik va sinamadik):

js
// ecosystem.config.cjs — PM2 sozlamasi (hujjatdan)
module.exports = {
  apps: [{
    name: "api",
    script: "./dist/server.js",
    exec_mode: "cluster", // Node cluster moduli
    instances: "max",     // har yadroga bitta ishchi
  }],
};

PM2 qo'shadi: yiqilgan ishchini qayta ishga tushirish, kodni yangilashda ishchilarni birma-bir almashtirish (zero-downtime reload), loglar, xotira oshsa qayta ishga tushirish. Windows'da u ham cluster ustida — «Kanon o'lchovi: 200 so'rov» bo'limidagi topilma unga ham tegishli bo'lishi mumkin (sinalmagan).

5.2 Konteyner replikalari

Bugungi ko'p loyihalarda cluster ham, PM2 ham ishlatilmaydi. Buning o'rniga bir xil ilova bir nechta konteynerda (Docker — 26-qism boshida o'rganamiz) ishga tushiriladi. Ularning oldida esa yuk taqsimlovchi (load balancer — nginx, bulut xizmati yoki Kubernetes) turadi. Har konteynerda — bitta oddiy, cluster'siz Node jarayoni.

Nega bu afzal?

  1. Bir xil yo'l, har qanday miqyos: 4 ta jarayon bitta mashinada yoki 40 ta jarayon 10 ta mashinada — kod o'zgarmaydi.
  2. Taqsimotni maxsus vosita qiladi: nginx va bulut balanserlari bu ish uchun yaratilgan, sozlanadi va o'lchanadi.
  3. Yiqilishni platforma boshqaradi: konteyner o'lsa, orkestrator yangisini ochadi — exit tinglovchisini o'zingiz yozmaysiz.
  4. Resurs chegaralari aniq: har konteynerga CPU va xotira limiti beriladi.
Usul Qachon
Bitta jarayon kichik sayt, CLI, ko'p hollarda boshlanish nuqtasi
cluster (qo'lda) bitta server, konteynersiz, o'rganish yoki maxsus holat
PM2 cluster mode bitta VPS, konteynersiz, tayyor boshqaruv kerak
Konteyner replikalari zamonaviy deploy, bir nechta server, bulut

Masalan, IlmHamroh'ning o'z serveri ham konteynerlarda ishlaydi: har xizmat alohida konteyner, ularning oldida nginx.

5.3 Kanon qarori: valyuta ga cluster kerak emas

valyuta — server emas, CLI. U bitta buyruqni bajaradi va chiqadi: tinglaydigan porti yo'q, parallel mijozlari yo'q. Cluster qo'shilsa, har ishga tushishda bir nechta Node jarayoni ochilardi (har biri ~38 MB xotira — kanonda bo'sh Node jarayoni 37.8 MB rss oldi — va o'nlab ms) — sof yo'qotish. Shuning uchun cluster faqat kanon tajribasida qoldi. Bu dars uchun "CLI qadami" o'rnida — o'sha tajriba (4-mashq).

6. Ko'p uchraydigan xatolar

6.1 "Cluster yukni teng taqsimlaydi" deb ishonish

Windows'da sukut bo'yicha bunday emas — 200/0/0/0. Taqsimotni o'lchang; kerak bo'lsa NODE_CLUSTER_SCHED_POLICY=rr.

6.2 Holatni ishchi xotirasida saqlash

Sessiya, savatcha, limitlar Map da — har ishchida boshqacha. Foydalanuvchi tasodifan "tizimdan chiqib ketadi". Umumiy holat — tashqi omborda.

6.3 Cheksiz qayta ishga tushirish

exit da shartsiz cluster.fork() — ishchi ishga tushishi bilan yiqilsa, cheksiz aylanish. Vaqt oynasi bilan cheklang va xabar bering.

6.4 Cluster'ni CPU-og'ir ish uchun ishlatish

Bitta so'rov 2 soniya hisoblasa, cluster uni tezlashtirmaydi — o'sha ishchi 2 soniya band bo'ladi. Og'ir hisob — worker_threads yoki pool; cluster — ko'p yengil so'rov uchun.

6.5 Konteyner ichida yana cluster

Har konteynerga 1 CPU berilgan, ichida esa instances: "max" — xotira bir necha baravar ko'p ketadi, foyda yo'q. Konteyner dunyosida masshtablash — konteynerlar soni bilan.

7. Mashqlar

1-mashq (oson): Nima bo'ladi?

Javob bering: (1) cluster'da 4 ishchi bor, har birida const kesh = new Map(). Foydalanuvchi bir kurs so'radi — u 2-ishchining keshiga tushdi. Keyingi so'rov 4-ishchiga tushsa, kesh ishlaydimi? (2) Bu holat xatomi?

Yechim

(1) Yo'q — 4-ishchining keshi bo'sh, u kursni qaytadan oladi. (2) Bu har doim ham xato emas. Kesh — "bo'lsa yaxshi" ma'lumot: har ishchi o'z keshini to'ldiradi, natija baribir to'g'ri, faqat birinchi so'rovlar sekinroq. Sessiya bilan farqi shu: sessiya yo'qolsa — foydalanuvchi tizimdan chiqadi (xato), kesh yo'qolsa — biroz sekinlik (qabul qilinadigan narx). Shuning uchun jadvalda kesh uchun "har ishchida alohida (ataylab)" varianti bor.

2-mashq (o'rta): Ishchilar soni va xabarlar

Asosiy jarayon 3 ta ishchi ochsin. Har ishchi asosiy jarayonga { id, yig } xabarini yuborsin: yig — 1 dan id × 1000 gacha sonlar yig'indisi (cluster.worker.id — ishchining raqami). Asosiy jarayon hamma xabarlarni olgach, ularni id bo'yicha tartiblab chiqarsin va ishchilarni o'chirsin (w.kill()). Eslatma: process.send() va cluster.on("message") — «Ishchi bilan xabar va qayta ishga tushirish» bo'limida.

Yechim
js
import cluster from "node:cluster";

if (cluster.isPrimary) {
  const natijalar = [];
  const ishchilar = [1, 2, 3].map(() => cluster.fork());
  cluster.on("message", (_w, xabar) => {
    natijalar.push(xabar);
    if (natijalar.length === ishchilar.length) {
      natijalar.sort((a, b) => a.id - b.id);
      for (const n of natijalar) {
        console.log(`ishchi ${n.id}: ${n.yig}`);
      }
      for (const w of ishchilar) w.kill();
    }
  });
} else {
  const { id } = cluster.worker;
  let yig = 0;
  for (let i = 1; i <= id * 1000; i++) yig += i;
  process.send({ id, yig });
}

Konsolda:

text
ishchi 1: 500500
ishchi 2: 2001000
ishchi 3: 4501500

Xabarlar istalgan tartibda kelishi mumkin — har ishchi alohida jarayon va kim birinchi tugashi oldindan ma'lum emas. Shuning uchun tartiblash shart: aks holda chiqish har ishga tushishda boshqacha bo'lardi. Ishchi ichida process.send — child_process darsidagi IPC kanali, cluster uni o'zi ochadi.

3-mashq (qiyin): Ehtiyotkor qayta ishga tushiruvchi

«Ishchi bilan xabar va qayta ishga tushirish» bo'limidagi qayta++ < 2 ni haqiqiy qoidaga almashtiring: oxirgi 1 soniyada 3 martadan ko'p yiqilish bo'lsa — qayta ishga tushirmasin va "juda tez yiqilyapti — to'xtadik" chiqarsin. Ishchi har safar 50 ms dan keyin 1 kodi bilan chiqsin. Natijada nechta ishchi ochiladi? Eslatma: yiqilish vaqtlarini massivda saqlang va 1 000 ms dan eskilarini tashlang (Date.now() yoki performance.now()).

Yechim
js
import cluster from "node:cluster";

if (cluster.isPrimary) {
  const OYNA_MS = 1000;
  const CHEGARA = 3;
  let yiqilishlar = [];
  cluster.on("exit", (w) => {
    const hozir = performance.now();
    yiqilishlar = yiqilishlar.filter((t) => hozir - t < OYNA_MS);
    yiqilishlar.push(hozir);
    console.log(`ishchi ${w.id} yiqildi`);
    if (yiqilishlar.length > CHEGARA) {
      console.log("juda tez yiqilyapti — to'xtadik");
      return;
    }
    cluster.fork();
  });
  cluster.fork();
} else {
  setTimeout(() => process.exit(1), 50);
}

Konsolda:

text
ishchi 1 yiqildi
ishchi 2 yiqildi
ishchi 3 yiqildi
ishchi 4 yiqildi
juda tez yiqilyapti — to'xtadik

To'rtta ishchi ochildi: birinchi uchta yiqilish chegaraga sig'adi, to'rtinchisida (1 soniya ichida 4 ta) to'xtaldi. Har ishchi ~50 ms + jarayon ochish vaqti yashaydi, shuning uchun 4 ta yiqilish bir soniyaga sig'adi. Agar ishchilar kamdan-kam yiqilsa (masalan, soatiga bir marta), eski vaqtlar filter bilan tashlanadi va qayta ishga tushirish davom etadi. PM2 va orkestratorlar xuddi shu g'oyani (kechikish bilan qayta ishga tushirish, backoff) ishlatadi.

4-mashq: CLI qadami — tajriba, loyihaga kirmaydi

valyuta ga kod qo'shilmaydi. «Kanon o'lchovi: 200 so'rov» bo'limidagi sinovni o'z kompyuteringizda ikki marta ishga tushiring: sukut bilan va NODE_CLUSTER_SCHED_POLICY=rr bilan. Natijangizni yozing: platforma, siyosat, taqsimot. Linux yoki macOS'da bo'lsangiz — sukut bo'yicha taqsimot qanday chiqdi?

Yechim

Kanon (Windows 11, Node 24.21.0): sukut — SCHED_NONE, [ 200 ]; rr bilan — [ 50, 50, 50, 50 ]. Linux/macOS'da hujjatga ko'ra sukut SCHED_RR, ya'ni teng taqsimot kutiladi — biz buni sinamadik, sizning natijangiz shu bo'shliqni to'ldiradi. Port band bo'lsa (EADDRINUSE), sinovdagi 3124 ni boshqasiga almashtiring. Sinov oxirida w.kill() bor — u bo'lmasa, ishchilar jarayonni tirik ushlab turadi va dastur tugamaydi.

8. Real ishda

  • Eski va o'rta loyihalar: VPS'da PM2 cluster mode bilan ishlaydigan Node API — juda ko'p uchraydigan manzara. Uni o'qish va sozlashni bilish kerak.
  • Zamonaviy deploy: Kubernetes, Docker Swarm, bulut xizmatlari — replikalar soni bilan masshtablash; ilova ichida cluster yo'q.
  • Arxitektura talabi: "server holatsiz bo'lsin" — cluster, replikalar va avtomatik masshtablashning umumiy sharti. Code review'da xotiradagi sessiya darhol savol tug'diradi.
  • Intervyu savollari: "Node qanday qilib ko'p yadroni ishlatadi?", "cluster va worker_threads farqi?", "Sticky session nima va undan qanday qochiladi?".

Xulosa

  • cluster.fork() butun Node jarayonini ko'paytiradi; ishchilar bitta portni bo'lishadi, xotirani esa bo'lishmaydi.
  • Taqsimot: Linux/macOS — round-robin (hujjat bo'yicha), Windows — OS; kanonda Windows'da 200 so'rovning hammasi bitta ishchiga tushdi.
  • NODE_CLUSTER_SCHED_POLICY=rr bilan — 50/50/50/50; round-robin ulanishlarni taqsimlaydi, so'rovlarni emas.
  • Ishchi yiqilsa — exit da qayta oching, lekin tez yiqilishlarni cheklang.
  • Umumiy holat — tashqarida; bugun ko'pincha cluster o'rniga konteyner replikalari.

Keyingi dars: AsyncLocalStorage — so'rov ID'sini har funksiyaga argument qilmasdan butun async zanjir bo'ylab olib yuramiz.

Manbalar

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
Node.js cluster: ko'p yadroli masshtablash va Windows tuzog'i — IlmHamroh