almessadi.
العودة إلى الفهرس

نود.جي إس لا يزال يتجمد عندما تضع عبء العمل على المعالج في الخيط الرئيسي_

نود ممتاز في إدخال/إخراج غير الحجب، لكن العمليات الثقيلة على المعالج المتزامنة لا تزال تعيق حلقة الأحداث. هذه التمييز هو المكان الذي تبدأ فيه العديد من الحوادث الإنتاجية.

تاريخ النشر14 أغسطس 2024
وقت القراءة7 min read

نود.جي إس جيد في تزامن إدخال/إخراج. وهو ليس جيدًا في التظاهر بأن عبء عمل المعالج غير متزامن فقط لأن دالة المعالج تستخدم async.

هذا التمييز مهم لأن العديد من الحوادث المتعلقة بالأداء لا تأتي من قواعد بيانات بطيئة أو شبكات بطيئة. بل تأتي من طلب واحد يقوم بالكثير من العمل المتزامن بينما ينتظر كل طلب آخر خلفه.

المثال المضلل

يبدو أن هذه المسار غير ضار للوهلة الأولى:

app.post("/webhook", async (req, res) => {
  const payload = JSON.parse(req.body.raw);
  await database.save(payload);
  res.send("ok");
});

نداء قاعدة البيانات غير متزامن. JSON.parse ليس كذلك.

إذا كان الحمل كبيرًا، يحدث التحليل على الخيط الرئيسي، ولا تستطيع حلقة الأحداث الاستمرار في خدمة الطلبات الواردة الأخرى حتى ينتهي هذا العمل.

ما الذي يعوق بالفعل

في خدمات نود الحقيقية، الأسباب المعتادة هي:

  • استدعاءات JSON.parse و JSON.stringify الضخمة
  • إنشاء الصور أو ملفات PDF
  • العمل في التشفير الذي يتم في المكان الخاطئ
  • العمل المتزامن الكبير على نظام الملفات
  • حلقات التعبير العادي أو التحويل المكلفة

الحل ليس "جعل كل شيء غير متزامن". الحل هو نقل أو إعادة تشكيل العمل.

خيارات أفضل

عندما يكون ذلك ممكنًا:

  • استخدم البث بدلاً من تخزين الأحمال الكبيرة
  • استخدم العمال لمهام عالية الحمل على المعالج
  • انقل التحويلات المكلفة بعيدًا عن المسارات الساخنة للطلبات

على سبيل المثال، خيوط العمال غالبًا ما تكون الحدود الأنظف للعمليات الثقيلة في الحساب:

import { Worker } from "node:worker_threads";

export function runHeavyTask(input: unknown) {
  return new Promise((resolve, reject) => {
    const worker = new Worker(new URL("./worker.js", import.meta.url), {
      workerData: input,
    });

    worker.once("message", resolve);
    worker.once("error", reject);
  });
}

هذا لا يجعل العمل أرخص. إنه يحافظ على حلقة الأحداث سريعة الاستجابة بينما يحدث العمل في مكان آخر.

المقايضة

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

قراءة إضافية