WisarWisar
Dasturlash kitobi/5-QISM — Nodejs18 daqiqa

5.22-bob: Navbatlar (Queues) — BullMQ, fon vazifalari, cron

5-QISM — Node.js Backend · 22-mavzu


1. Kirish va motivatsiya

Redis'ni 5.21-bob o'rgandik. Endi uning ustida quriladigan muhim mexanizmni — navbat (queue) va fon vazifalari (background jobs) ni — o'rganamiz. Bu — yuqori sifatli, masshtablanadigan backend'ning muhim qismi.

Muammo shunday: ba'zi vazifalar sekin yoki og'ir — email yuborish (5.19, bir necha sekund), rasm qayta ishlash (5.11, CPU), hisobot tayyorlash, tashqi API chaqirish, ko'p foydalanuvchiga bildirishnoma. Agar bularni so'rov ichida bajarsangiz — foydalanuvchi kutadi (sekin UX), va so'rov vaqti tugashi (timeout) mumkin. Yomoni — agar shu paytda xato bo'lsa (email server o'chiq), butun so'rov buziladi.

Yechim — navbat (queue): og'ir vazifani darrov bajarmasdan, "navbatga" qo'yasiz va foydalanuvchiga tez javob berasiz. Keyin alohida jarayon (worker) navbatdan vazifani olib, fonda bajaradi. Foydalanuvchi kutmaydi; vazifa xato bersa — qayta urinadi (retry); ko'p vazifa bo'lsa — navbatda turadi (server bosib qolmaydi). O'zbekistonda buni BullMQ (Redis ustida — 5.21) bilan quramiz. Va cron bilan — rejalashtirilgan vazifalar (har kuni soat 9da hisobot, har soat tozalash).

O'xshatish: navbat — restoran oshxonasi. Mijoz buyurtma beradi (so'rov), ofitsiant uni oshxonaga qog'ozga yozib beradi (navbatga qo'yadi) va mijozga "qabul qilindi" deydi (tez javob). Mijoz stolda kutadi (boshqa ish qiladi), oshpaz (worker) buyurtmalarni navbat bo'yicha tayyorlaydi (fon). Agar taom kuyib ketsa — qayta tayyorlaydi (retry). Ofitsiant har buyurtmada oshxonada turib qolmaydi (so'rov bloklanmaydi). Cron — "har kuni ertalab non yopish" (rejalashtirilgan, avtomatik).

Nega muhim?

  • Tez UX — og'ir vazifa fonda; foydalanuvchi kutmaydi.
  • Ishonchlilik — xato bo'lsa qayta urinish (retry); vazifa yo'qolmaydi.
  • Masshtab — ko'p vazifa navbatda; worker'lar parallel ishlaydi.
  • Rejalashtirilgan — cron: davriy hisobot, tozalash, eslatma.

2. Nazariya — chuqur tushuntirish

2.1. Sinxron vs navbat (muammo)

text
   So'rov ichida og'ir vazifa:
  POST /signup  user yarat  email yubor (3 sek!)  rasm resize (2 sek!)  javob
   foydalanuvchi 5 sekund kutadi; email server o'chiq bo'lsa — butun so'rov xato (5.10)

   Navbat bilan:
  POST /signup  user yarat  navbatga "email", "resize" qo'sh  javob (tez!)
   worker fonda email/resize bajaradi (foydalanuvchi kutmaydi)

2.2. Navbat (queue) tushunchasi

Queue (navbat) — bajariladigan vazifalar ro'yxati; vazifalar producer (ishlab chiqaruvchi) tomonidan qo'shiladi, worker (ishchi) tomonidan bajariladi (bullmq):

text
  Producer (API)          Queue (Redis)          Worker (alohida jarayon)
  "email yubor" ───────▶  [job1, job2, job3] ───────▶ job oladi, bajaradi
  (tez qo'shadi)           (saqlanadi)                 (fonda, navbat bo'yicha)

Uch qism: Queue — navbat (vazifalar saqlanadi — Redis); Producer — vazifa qo'shuvchi (odatda API — 5.6); Worker — vazifani bajaruvchi (alohida jarayon). Producer tez qo'shadi; worker o'z tezligida bajaradi.

2.3. BullMQ nima (Redis ustida)

BullMQ — Node.js uchun eng mashhur navbat kutubxonasi (eski Bull'ning vorisi, TypeScript bilan, Redis Streams asosida — bullmq.io). Redis 5.21-bob ustida ishlaydi:

bash
npm install bullmq          # 5.2-bob — Redis kerak (5.21)

BullMQ imkoniyatlari (bullmq):

text
   Delayed jobs    — kechiktirib bajarish (5 daqiqadan keyin)
   Repeatable/cron — takrorlanuvchi (har kuni — 2.10)
   Retries         — xatoda qayta urinish 2.8-bob
   Priorities      — muhimlik tartibi
   Rate limiting   — sekundiga N vazifa
   Concurrency     — parallel bajarish 2.9-bob
   Flows           — bog'liq vazifalar zanjiri

2.4. Queue yaratish (producer)

Queue — vazifa qo'shish uchun (5.21: Redis ulanish):

js
import { Queue } from "bullmq";

const emailQueue = new Queue("email", {                // "email" — navbat nomi
  connection: { host: "localhost", port: 6379 },       // Redis (5.21)
});

// Vazifa qo'shish (producer — 2.2)
await emailQueue.add("welcome", {                       // "welcome" — job nomi
  to: "user@a.uz", ism: "Ali",                          // job ma'lumoti (data)
});

add(nom, data) — navbatga vazifa qo'shadi (tez — faqat Redis'ga yozadi). API shu yerda — so'rovni bloklamasdan davom etadi 2.1-bob.

2.5. Worker yaratish (vazifani bajarish)

Worker — navbatdan vazifa olib, bajaradi (odatda alohida fayl/jarayon — 2.7):

js
import { Worker } from "bullmq";

const worker = new Worker("email", async (job) => {     // "email" navbatini tinglaydi
  // job.name — "welcome"; job.data — { to, ism }
  if (job.name === "welcome") {
    await emailYubor(job.data);                          // haqiqiy ish (5.19)
  }
}, { connection: { host: "localhost", port: 6379 } });

worker.on("completed", (job) => console.log(` ${job.id} bajarildi`));   // (5.12)
worker.on("failed", (job, err) => console.error(` ${job.id}:`, err));   // (2.8)

Worker fonda doim ishlaydi: u navbatni "tinglaydi"; yangi vazifa kelsa — oladi, bajaradi. API'dan alohida ishlaydi 2.7-bob.

2.6. Job hayot sikli (holatlar)

text
  waiting    — navbatda (worker hali olmagan)
  active     — worker bajarmoqda
  completed  — muvaffaqiyatli tugadi
  failed     — xato (retry'lar tugagach — 2.8)
  delayed    — kechiktirilgan (vaqti kelmagan — 2.10)
text
  add()  [waiting]  worker oladi  [active] 
            ├─ muvaffaqiyat  [completed]
            └─ xato  retry 2.8-bob  tugasa  [failed]

2.7. Producer va Worker — alohida jarayon (muhim)

Worker'ni API'dan ALOHIDA jarayonda ishlating (best practices, oneuptime):

text
  Jarayon 1: API server (Express — 5.6) — producer (vazifa qo'shadi)
  Jarayon 2: Worker — vazifalarni bajaradi (alohida)

  Nega: og'ir worker (rasm resize — CPU) API'ni bloklamasin (5.1: event loop);
        worker yiqilsa, API ishlayveradi; alohida masshtablanadi (ko'p worker)

Kichik loyihada bir jarayonda bo'lishi mumkin, lekin production'da alohida (alohida worker.js, PM2/Docker bilan — 10.7). Bu — masshtab va barqarorlik uchun.

2.8. Retry (qayta urinish) — ishonchlilik

Navbatning kuchi: vazifa xato bersa (email server vaqtincha o'chiq), avtomatik qayta urinadi (bullmq):

js
await emailQueue.add("welcome", data, {
  attempts: 3,                                           // 3 marta urin
  backoff: { type: "exponential", delay: 5000 },        // 5s, 10s, 20s (orasini oshirib)
});
// 3 marta ham xato bersa  failed 2.6-bob; dead letter (qo'lda ko'rish)

Backoff — qayta urinishlar orasidagi kutish. Exponential (5s10s20s) — har urinishda ko'proq kutadi (server tiklanishiga vaqt beradi). Bu — sinxron kodda yo'q xususiyat (xato bo'lsa, tamom). Navbat — ishonchlilik beradi.

2.9. Concurrency (parallel bajarish)

Worker bir vaqtda nechta vazifa bajarishini sozlash (bullmq):

js
const worker = new Worker("email", processor, {
  connection,
  concurrency: 10,                                       // bir vaqtda 10 ta vazifa
});

Concurrency tanlovi: vazifa asosan kutadi (tarmoq — email, API) yuqori concurrency (10-50, parallel kutish foydali). Vazifa CPU-og'ir (rasm resize) past (1-4, CPU bloklanadi — 5.1). Noto'g'ri sozlash — sekinlik yoki xotira muammosi.

2.10. Delayed va Repeatable (cron) jobs

Delayed — kechiktirib bajarish; Repeatable — takroriy (cron — bullmq):

js
// Delayed — 1 soatdan keyin (eslatma, kechiktirilgan email)
await queue.add("eslatma", data, { delay: 60 * 60 * 1000 });   // 1 soat (ms)

// Repeatable — har kuni soat 9:00 (cron — 2.11)
await queue.add("kunlik-hisobot", {}, {
  repeat: { pattern: "0 9 * * *" },                     // cron ifodasi (2.11)
});

Delayed — "shu vaqtdan keyin" (buyurtma 30 daqiqada tasdiqlanmasa — bekor; trial tugashidan oldin eslatma). Repeatable — "muntazam" (har kun, har soat — hisobot, tozalash, sinxronizatsiya).

2.11. Cron ifodalari (rejalashtirish sintaksisi)

Cron — vazifani qachon takrorlashni belgilovchi standart ifoda (5 maydon):

text
  ┌── daqiqa (0-59)
  │ ┌── soat (0-23)
  │ │ ┌── oyning kuni (1-31)
  │ │ │ ┌── oy (1-12)
  │ │ │ │ ┌── hafta kuni (0-6, 0=yakshanba)
  │ │ │ │ │
  * * * * *

  Misollar:
  "0 9 * * *"     — har kuni soat 9:00
  "*/15 * * * *"  — har 15 daqiqada
  "0 0 * * 0"     — har yakshanba yarim tunda
  "0 */2 * * *"   — har 2 soatda

Cron — Linux'dan kelgan standart (10: DevOps). BullMQ repeatable, yoki alohida node-cron paketi shu sintaksisni ishlatadi. O'rganishga arziydi (ko'p joyda).

2.12. node-cron (oddiy rejalashtirish — BullMQ'siz)

Oddiy davriy vazifa uchun (Redis/navbat shart bo'lmasa) — node-cron:

js
import cron from "node-cron";

cron.schedule("0 9 * * *", async () => {                // har kuni 9:00 (2.11)
  await kunlikHisobotYubor();                            // vazifa
});

node-cron vs BullMQ repeatable: node-cron — sodda, lekin bir jarayonda (server yiqilsa, o'tkazib yuboradi; ko'p serverda — har birida ishlaydi — dublikat!). BullMQ repeatable — Redis'da (ishonchli, ko'p serverda bir marta — 2.10). Oddiy/bitta server — node-cron; jiddiy/ko'p server — BullMQ.

2.13. Idempotentlik (muhim — retry xavfsizligi)

Vazifa idempotent bo'lishi kerak: ikki marta bajarilsa ham (retry — 2.8), bir martalik ta'sir qilsin (best practices):

text
   Idempotent emas:
  "to'lov" job retry bo'ldi  IKKI MARTA pul yechildi (falokat!)

   Idempotent:
  job ID/belgi tekshiriladi  "bu allaqachon bajarilgan"  o'tkazib yubor
   retry bo'lsa ham, bir marta ta'sir

Nega muhim: retry (timeout'dan keyin) vazifani qayta bajarishi mumkin. Email — ikki marta kelsa, mayli. Lekin to'lov, pul, buyurtma — ikki marta — falokat. Vazifa "allaqachon bajarilganmi?" tekshirishi shart (DB belgisi, idempotency key).

2.14. Redis xotirasini boshqarish (tozalash)

Bajarilgan vazifalar Redis'da qoladi (default) — xotira to'ladi (best practices):

js
await queue.add("email", data, {
  removeOnComplete: 100,                                 // oxirgi 100 muvaffaqiyatni saqla
  removeOnFail: 1000,                                    // oxirgi 1000 xatoni saqla
});
// yoki removeOnComplete: { age: 3600 } — 1 soatdan eskini o'chir

removeOnComplete sozlash MAJBURIY: aks holda har bajarilgan vazifa Redis'da qoladi — kuniga 10K vazifa = haftalar ichida gigabaytlar (best practices). Muvaffaqiyatlilarni tez o'chiring; xatolarni biroz saqlang (tahlil uchun).

2.15. BullMQ Redis ulanishi nuansi

BullMQ ioredis bilan ishlatilganda maxsus sozlama (bullmq):

js
import { Queue } from "bullmq";
import Redis from "ioredis";

const connection = new Redis({
  host: "localhost", port: 6379,
  maxRetriesPerRequest: null,                            //  BullMQ uchun null SHART
});
const queue = new Queue("email", { connection });

maxRetriesPerRequest: null — BullMQ bloklovchi buyruq (BLPOP) ishlatadi; ioredis default'i bilan xato beradi. BullMQ ulanishida null qo'yish shart (bullmq hujjati).

2.16. Use-case'lar va monitoring

text
  Email/SMS yuborish     — fonda (5.19, 5.18)
  Rasm/video qayta ishlash — resize, transcode (5.11, CPU)
  Hisobot/eksport        — og'ir hisoblash, PDF/Excel
  Ommaviy bildirishnoma  — ko'p foydalanuvchiga
  Tashqi API sinxronizatsiya — to'lov, yetkazib berish holati
  Rejalashtirilgan       — kunlik hisobot, tozalash, eslatma (cron — 2.10)

  Monitoring: Bull Board / BullMQ UI — navbatlarni vizual ko'rish (job, xato, retry)

3. Sintaksis — tez ma'lumotnoma

js
import { Queue, Worker } from "bullmq";
const connection = { host, port, maxRetriesPerRequest: null };   // (2.15)

// Producer (vazifa qo'shish — 2.4)
const queue = new Queue("email", { connection });
await queue.add("welcome", data, {
  attempts: 3, backoff: { type: "exponential", delay: 5000 },    // retry (2.8)
  removeOnComplete: 100,                                          // tozalash (2.14)
});

// Delayed/repeatable (2.10)
await queue.add("x", data, { delay: 3600000 });                  // 1 soat
await queue.add("x", {}, { repeat: { pattern: "0 9 * * *" } });  // cron (2.11)

// Worker (bajarish — alohida jarayon — 2.5, 2.7)
new Worker("email", async (job) => { /* ish */ }, { connection, concurrency: 10 });

// node-cron (oddiy — 2.12): cron.schedule("0 9 * * *", fn)

4. Batafsil kod namunalari

Misol 1 — Queue va Worker (asosiy — 2.4, 2.5)

js
// queue.js — producer (2.4)
import { Queue } from "bullmq";
import { config } from "./config/index.js";            // (5.8)

const connection = {
  host: config.redis.host, port: config.redis.port,
  maxRetriesPerRequest: null,                            // BullMQ uchun (2.15)
};
export const emailQueue = new Queue("email", { connection });

// Vazifa qo'shish
export const emailNavbatga = (data) =>
  emailQueue.add("welcome", data, {
    attempts: 3,                                         // retry (2.8)
    backoff: { type: "exponential", delay: 5000 },
    removeOnComplete: 100,                               // tozalash (2.14)
    removeOnFail: 500,
  });
js
// worker.js — ALOHIDA jarayon (2.7)
import { Worker } from "bullmq";
import { emailYubor } from "./services/email.js";        // (5.19)

const worker = new Worker("email", async (job) => {
  console.log(`Bajarilmoqda: ${job.name} (${job.id})`);
  if (job.name === "welcome") {
    await emailYubor(job.data);                           // haqiqiy ish (5.19)
  }
}, { connection, concurrency: 10 });                      // (2.9)

worker.on("completed", (job) => console.log(` ${job.id}`));        // (5.12)
worker.on("failed", (job, err) => console.error(` ${job.id}:`, err.message));   // (2.8)

Misol 2 — API'da ishlatish (so'rovni bloklamaslik — 2.1)

js
import { emailNavbatga } from "../queue.js";

// Ro'yxatdan o'tish — email FONDA (so'rov tez — 2.1)
export const signup = async (req, res, next) => {
  try {
    const user = await User.create(req.body);            // DB (6)
    // Email'ni NAVBATGA qo'y (kutmaymiz! — 2.1)
    await emailNavbatga({ to: user.email, ism: user.ism });
    // Darrov javob (email fonda yuboriladi)
    res.status(201).json({ success: true, user: { id: user.id, email: user.email } });
  } catch (err) { next(err); }
};
// Foydalanuvchi email yuborilishini KUTMAYDI — tez javob (2.1)

Misol 3 — Retry va backoff (ishonchlilik — 2.8)

js
await emailQueue.add("welcome", data, {
  attempts: 5,                                           // 5 marta urin (2.8)
  backoff: { type: "exponential", delay: 3000 },        // 3s, 6s, 12s, 24s
});

// Worker xatoni qayd qiladi; tugasa failed (2.6)
worker.on("failed", (job, err) => {
  if (job.attemptsMade >= job.opts.attempts) {
    console.error(`Job ${job.id} butunlay muvaffaqiyatsiz:`, err.message);   // (5.12)
    // dead letter — admin'ga xabar; qo'lda ko'rish
  }
});

Misol 4 — Delayed job (kechiktirilgan — 2.10)

js
// Buyurtma 30 daqiqada tasdiqlanmasa — bekor qil (delayed — 2.10)
export const buyurtmaYarat = async (req, res, next) => {
  try {
    const buyurtma = await Order.create({ ...req.body, holat: "kutilmoqda" });
    // 30 daqiqadan keyin tekshirish vazifasi (2.10)
    await orderQueue.add("avtobekor", { orderId: buyurtma.id },
      { delay: 30 * 60 * 1000 });                        // 30 daqiqa
    res.status(201).json({ success: true, id: buyurtma.id });
  } catch (err) { next(err); }
};

// Worker: 30 daqiqadan keyin ishlaydi
new Worker("order", async (job) => {
  if (job.name === "avtobekor") {
    const order = await Order.findById(job.data.orderId);
    if (order?.holat === "kutilmoqda") {                  // hali tasdiqlanmagan
      order.holat = "bekor"; await order.save();          // avtobekor (6)
    }
  }
}, { connection });

Misol 5 — Repeatable job (cron — kunlik hisobot — 2.10, 2.11)

js
// Har kuni soat 9:00 da hisobot (repeatable — 2.10, 2.11)
await reportQueue.add("kunlik-hisobot", {}, {
  repeat: { pattern: "0 9 * * *" },                      // cron (2.11)
  removeOnComplete: 10,
});

// Worker
new Worker("report", async (job) => {
  if (job.name === "kunlik-hisobot") {
    const stats = await hisobotTayyorla();                // og'ir hisoblash (6)
    await emailYubor({ to: "admin@mana.uz", subject: "Kunlik hisobot", html: stats });   // (5.19)
  }
}, { connection });

Misol 6 — node-cron (oddiy — BullMQ'siz — 2.12)

js
import cron from "node-cron";                            // npm install node-cron

// Har kuni yarim tunda eski sessiyalarni tozalash (2.12)
cron.schedule("0 0 * * *", async () => {
  const ochirildi = await Session.deleteMany({ expiresAt: { $lt: new Date() } });   // (6)
  console.log(`${ochirildi.deletedCount} eski sessiya o'chirildi`);   // (5.12)
});

// Har 15 daqiqada tashqi narxlarni sinxronizatsiya (2.11)
cron.schedule("*/15 * * * *", async () => {
  await narxlarniYangila();
});
//  Bir jarayonda — ko'p serverda dublikat 2.12-bob; jiddiy uchun BullMQ

Misol 7 — Idempotent vazifa (retry xavfsizligi — 2.13)

js
// To'lov vazifasi — IKKI MARTA bajarilmasin (2.13, 14)
new Worker("payment", async (job) => {
  const { orderId, idempotencyKey } = job.data;

  // 1. Allaqachon bajarilganmi? (idempotency — 2.13)
  const mavjud = await Payment.findOne({ idempotencyKey });
  if (mavjud) {
    console.log("Bu to'lov allaqachon bajarilgan — o'tkazib yuborildi");   // retry'da
    return mavjud;                                        // qayta yechmaymiz!
  }

  // 2. To'lovni bajarish
  const result = await tolovProvayder.charge(orderId);
  await Payment.create({ orderId, idempotencyKey, ...result });   // belgi (6)
  return result;
}, { connection });
// Retry bo'lsa ham — idempotencyKey bir xil  ikki marta yechilmaydi (2.13)

Misol 8 — Concurrency va rate limit (2.9)

js
// Tarmoq vazifasi — yuqori concurrency (2.9)
new Worker("email", emailProcessor, {
  connection,
  concurrency: 20,                                       // 20 ta parallel (kutadi — 2.9)
});

// CPU vazifasi — past concurrency (2.9)
new Worker("image", imageProcessor, {
  connection,
  concurrency: 2,                                        // 2 ta (CPU og'ir — 5.1)
});

// Rate limit — SMS provayder cheklovi (5.18)
const smsQueue = new Queue("sms", { connection });
new Worker("sms", smsProcessor, {
  connection,
  limiter: { max: 10, duration: 1000 },                  // sekundiga 10 SMS
});

Misol 9 — Graceful shutdown (worker — 5.10)

js
// Worker'ni xavfsiz to'xtatish (joriy vazifani tugatib — 5.10)
const worker = new Worker("email", processor, { connection });

process.on("SIGTERM", async () => {
  console.log("Worker yopilmoqda...");
  await worker.close();                                  // joriy vazifani tugatadi (5.10)
  process.exit(0);
});
// Deploy paytida (10) yarim bajarilgan vazifa yo'qolmaydi

5. To'g'ri va noto'g'ri holatlar

1) Og'ir vazifani so'rov ichida bajarish

js
//  foydalanuvchi kutadi; xatoda so'rov buziladi (2.1)
await emailYubor(...); res.json({ ok: true });

//  navbatga
await emailQueue.add("welcome", data); res.json({ ok: true });

2) Vazifa idempotent emas

text
 to'lov retry  ikki marta yechiladi (falokat — 2.13)
 idempotency key bilan tekshiring (Misol 7)

3) removeOnComplete'siz

js
//  Redis to'lib ketadi (2.14)
await queue.add("email", data);

//  tozalash
await queue.add("email", data, { removeOnComplete: 100 });

4) Worker API bilan bir jarayonda (production)

text
 CPU-og'ir worker API'ni bloklaydi (5.1, 2.7)
 alohida worker.js (PM2/Docker — 10.7)

5) maxRetriesPerRequest null emas

js
//  BullMQ xato beradi (2.15)
new Redis({ host, port });

//  null
new Redis({ host, port, maxRetriesPerRequest: null });

6. Keng tarqalgan xatolar va yechimlari

Xato 1 — maxRetriesPerRequest xatosi

Sababi: BullMQ ulanishida null emas 2.15-bob. Yechimi: new Redis({ maxRetriesPerRequest: null }).

Xato 2 — Worker vazifani olmaydi

Sababi: queue va worker nomi mos emas, yoki worker ishga tushmagan 2.5-bob. Yechimi: bir xil navbat nomi; worker jarayoni ishlayotganini tekshiring.

Xato 3 — Redis xotirasi to'ldi

Sababi: removeOnComplete yo'q 2.14-bob. Yechimi: removeOnComplete/removeOnFail sozlang.

Xato 4 — Vazifa ikki marta bajarildi

Sababi: retry + idempotent emas 2.13-bob. Yechimi: idempotency key (Misol 7).

Xato 5 — Cron ko'p serverda bir necha marta ishladi

Sababi: node-cron har serverda 2.12-bob. Yechimi: BullMQ repeatable (Redis — bir marta — 2.10); yoki lider saylash.

Xato 6 — Vazifa "failed" lekin sababi noma'lum

Sababi: xato log qilinmagan. Yechimi: worker.on("failed") da log 5.12-bob; Bull Board monitoring 2.16-bob.


7. Integratsiya — bu mavzu stack'ning qayerida uchraydi

  • Redis 5.21-bob: BullMQ Redis ustida.
  • Email/SMS (5.19, 5.18): fonda yuborish.
  • File upload 5.11-bob: rasm/video qayta ishlash (fon).
  • Error handling 5.10-bob: retry, failed.
  • Logger 5.12-bob: vazifa holati, xato.
  • Env 5.8-bob: Redis ulanish.
  • DevOps 10.7-bob: worker alohida jarayon (PM2/Docker); cron.
  • NestJS 8.22-bob: @nestjs/bullmq, @nestjs/schedule — shu g'oya.
  • Mikroservis (9): navbat — servislar orasida aloqa.

8. Eng yaxshi amaliyotlar (best practices)

  • Og'ir/sekin vazifani navbatga (so'rovni bloklamasin — 2.1).
  • Worker alohida jarayonda (API'dan — production — 2.7, 10.7).
  • Retry + backoff (ishonchlilik — 2.8); exponential.
  • Idempotentlik (retry xavfsizligi — to'lov! — 2.13, 14).
  • removeOnComplete/removeOnFail (Redis xotira — 2.14).
  • Concurrency vazifa turiga qarab (tarmoq — yuqori, CPU — past — 2.9).
  • maxRetriesPerRequest: null (BullMQ ulanishi — 2.15).
  • Cron: BullMQ repeatable (ko'p server — 2.10) yoki node-cron (oddiy — 2.12).
  • Graceful shutdown (worker.close — 2.9-misol, 5.10).
  • Monitoring (Bull Board — xato/retry kuzatish — 2.16); failed'ni log 5.12-bob.

9. Amaliy loyiha: "Fon Vazifalari va Rejalashtirish Tizimi"

Navbat va fon vazifalarini professional darajada mustahkamlash.

Maqsad

BullMQ bilan fon vazifalari tizimini qurish: email/SMS navbati, retry, delayed va repeatable (cron) vazifalar, idempotentlik va monitoring.

Talablar (requirements)

  1. Queue + Worker: email navbati; producer (API) va worker (alohida) — Misol 1, 2.4, 2.5, 2.7.
  2. API integratsiya: ro'yxat/buyurtmada email/SMS navbatga (so'rov tez — Misol 2, 2.1).
  3. Retry + backoff: xatoda qayta urinish (exponential — Misol 3, 2.8).
  4. Delayed: buyurtma avtobekor (30 daqiqa — Misol 4, 2.10).
  5. Repeatable (cron): kunlik hisobot (Misol 5, 2.10, 2.11).
  6. Idempotentlik: to'lov/muhim vazifa ikki marta bajarilmasin (Misol 7, 2.13).
  7. Concurrency: tarmoq (yuqori) va CPU (past) vazifalar (Misol 8, 2.9).
  8. Tozalash: removeOnComplete/Fail 2.14-bob.
  9. Graceful shutdown: worker.close (Misol 9, 5.10).
  10. (Bonus) Monitoring: Bull Board 2.16-bob.
  11. (Bonus) node-cron: oddiy tozalash vazifasi (Misol 6, 2.12).

Maslahatlar (hint)

  • maxRetriesPerRequest: null (2.15, 1-xato).
  • Worker alohida worker.js (2.7, 4-xato).
  • API: queue.add(...) — kutmasdan 2.1-bob.
  • Retry: attempts + backoff 2.8-bob.
  • Cron: repeat: { pattern: "0 9 * * *" } 2.11-bob.
  • Idempotency key (to'lov — 2.13, 2-xato).
  • removeOnComplete (3-xato).

"Tayyor" mezonlari (acceptance criteria)

  • Queue + Worker (alohida jarayon) ishlaydi.
  • API vazifani navbatga qo'yadi (so'rov tez).
  • Retry + backoff (xatoda qayta urinish).
  • Delayed vazifa (kechiktirilgan) ishlaydi.
  • Repeatable (cron) — davriy vazifa.
  • Idempotentlik (ikki marta bajarilmaydi).
  • Concurrency to'g'ri sozlangan.
  • removeOnComplete bilan tozalash.
  • Graceful shutdown.
  • (Bonus) Bull Board / node-cron.

Yechim kodi ataylab berilmagan — bu loyihani o'zingiz yozib ko'ring.


10. Xulosa va keyingi bobga ko'prik

Bu bobda masshtablanadigan backend'ning muhim qismini — navbatlar va fon vazifalari — o'rgandik:

  • Sinxron muammosi (og'ir vazifa so'rovni bloklaydi — 2.1) navbat (Queue/Producer/Worker — 2.2).
  • BullMQ (Redis ustida — 2.3); Queue (qo'shish — 2.4), Worker (bajarish, alohida jarayon — 2.5, 2.7); job hayot sikli 2.6-bob.
  • Retry + backoff (ishonchlilik — 2.8); concurrency (parallel — 2.9); delayed/repeatable (cron — 2.10, 2.11); node-cron (oddiy — 2.12).
  • Idempotentlik (retry xavfsizligi — to'lov! — 2.13); Redis tozalash (removeOnComplete — 2.14); BullMQ ulanish nuansi 2.15-bob.

Keyingi bob — 5.23-bob: API hujjatlari — Swagger / OpenAPI. Backend'ni qurdik; endi uni hujjatlashni o'rganamiz: boshqa dasturchilar (frontend, jamoa) API'ngizdan qanday foydalanishini biladigan, interaktiv hujjat — Swagger/OpenAPI bilan. Bu — 5-QISM (Node.js Backend) ning yakuniy bobi; undan keyin 6-QISM (Ma'lumotlar bazasi) boshlanadi.


Foydalanilgan rasmiy/ishonchli manbalar

  • bullmq.io — BullMQ (Queue, Worker, retry, delayed, repeatable, concurrency, connection)
  • DEV/OneUptime — Background jobs with BullMQ & Redis 2026 (worker patterns, idempotency)
  • crontab cron syntax; node-cron (npm)

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
5.22-bob: Navbatlar (Queues) — BullMQ, fon vazifalari, cron — Wisar