چگونگی مدیریت هزاران درخواست توسط Node.js

مردم می‌گویند Node.js تک‌رشته‌ای (single-threaded) است.

با این حال، این محیط هزاران درخواست را مدیریت می‌کند، فایل‌ها را می‌خواند و بدون توقف، فراخوانی‌های API انجام می‌دهد.

این کار چگونه انجام می‌شود؟

پاسخ libuv است.

libuv یک کتابخانه C است. این کتابخانه قابلیت‌های I/O ناهمگام (asynchronous) و غیرمسدودکننده (non-blocking) را به Node.js می‌بخشد. جاوااسکریپت به تنهایی نمی‌تواند فایل‌ها را بخواند یا سوکت‌های شبکه را مدیریت کند. Node.js از libuv برای تعامل با سیستم‌عامل شما استفاده می‌کند.

بدون libuv، هر بار که فایلی را می‌خوانید، جاوااسکریپت متوقف می‌شود. اپلیکیشن شما غیرقابل پاسخگویی خواهد شد.

با وجود libuv، خواندن فایل در پس‌زمینه انجام می‌شود و جاوااسکریپت به اجرای سایر کدها ادامه می‌دهد.

مثال:

console.log("Start");

fs.readFile("data.txt", "utf8", (err, data) => {
  console.log(data);
});

console.log("End");

خروجی: Start End (محتویات فایل)

Node.js عبارت "End" را قبل از اتمام خواندن فایل چاپ می‌کند. این محیط منتظر نمی‌ماند.

نحوه مدیریت کد شما توسط libuv:

حلقه رویداد (Event Loop): libuv حلقه‌ای را اجرا می‌کند که بررسی می‌کند آیا وظایف تمام شده‌اند یا خیر. وقتی وظایف تکمیل می‌شوند، callbackها را در یک صف قرار می‌دهد. • استخر رشته‌ها (Thread Pool): جاوااسکریپت از یک رشته استفاده می‌کند. libuv از مجموعه‌ای از رشته‌های کارگر (worker threads) استفاده می‌کند. به طور پیش‌فرض، این استخر دارای ۴ رشته است. این رشته‌ها وظایف سنگین را مدیریت می‌کنند، مانند:

  • عملیات سیستم فایل
  • جستجوهای DNS
  • فشرده‌سازی
  • رمزنگاری • شبکه (Networking): libuv سوکت‌های HTTP، TCP و UDP را مدیریت می‌کند. این امر به سرورها اجازه می‌دهد تا همزمان چندین اتصال را مدیریت کنند. • تایمرها (Timers): libuv توابع setTimeout و setInterval را مدیریت می‌کند.

جریان اجرا به این صورت است:

  1. جاوااسکریپت کد شما را اجرا می‌کند.
  2. libuv وظایف سنگین را به پس‌زمینه می‌برد.
  3. جاوااسکریپت به خط بعدی ادامه می‌دهد.
  4. وقتی وظیفه تمام شد، libuv به Event Loop اطلاع می‌دهد.
  5. حلقه رویداد (Event Loop) callback شما را اجرا می‌کند.

یک پیتزافروشی را تصور کنید.

بدون libuv، شما جلوی پیشخوان می‌ایستید و هر ده ثانیه یک بار می‌پرسید "آیا غذای من آماده است؟". شما صف را مسدود می‌کنید.

با وجود libuv، شما سفارش می‌دهید، می‌نشینید و منتظر یک اعلان می‌مانید. تا زمانی که پیتزا آماده شود، شما آزاد هستید تا کارهای دیگر انجام دهید.

خلاصه:

• اجرای جاوااسکریپت: موتور V8 • حلقه رویداد: libuv • ورودی/خروجی فایل: libuv • شبکه: libuv • تایمرها: libuv

libuv موتوری است که Node.js را سریع نگه می‌دارد.

منبع: https://dev.to/kavindotdev/understanding-libuv-the-engine-behind-nodejs-asynchronous-programming-3n7o