איך Node.js מטפל באלפי בקשות
אנשים אומרים ש-Node.js הוא single-threaded.
ובכל זאת, הוא מטפל באלפי בקשות, קורא קבצים ומבצע קריאות API מבלי לעצור.
איך זה עובד?
התשובה היא libuv.
libuv היא ספריית C. היא מעניקה ל-Node.js יכולות I/O אסינכרוניות ולא חוסמות (non-blocking). JavaScript לא יכולה לקרוא קבצים או לנהל network sockets בעצמה. Node.js משתמש ב-libuv כדי לתקשר עם מערכת ההפעלה שלך.
ללא libuv, JavaScript הייתה עוצרת בכל פעם שקוראים קובץ. האפליקציה שלך הייתה הופכת ללא מגיבה.
עם libuv, הקובץ נקרא ברקע. JavaScript ממשיכה להריץ קוד אחר.
דוגמה:
console.log("Start");
fs.readFile("data.txt", "utf8", (err, data) => { console.log(data); });
console.log("End");
פלט: Start End (תוכן הקובץ)
Node.js מדפיס "End" לפני שהקובץ סיים להיקרא. הוא לא מחכה.
איך libuv מנהלת את הקוד שלך:
• The Event Loop: libuv מריצה את הלופ שבודק אם משימות הסתיימו. היא מכניסה callbacks לתור כאשר המשימות מסתיימות. • Thread Pool: JavaScript משתמשת בתהליכון (thread) אחד. libuv משתמשת במאגר (pool) של worker threads. כברירת מחדל, למאגר הזה יש 4 threads. ה-threads הללו מטפלים במשימות כבדות כמו:
- פעולות במערכת הקבצים (File system operations)
- שאילתות DNS (DNS lookups)
- דחיסה (Compression)
- קריפטוגרפיה (Cryptography) • Networking: libuv מנהלת sockets של HTTP, TCP ו-UDP. זה מאפשר לשרתים לטפל בהרבה חיבורים בו-זמנית. • Timers: libuv מטפלת ב-setTimeout וב-setInterval.
זרימת ההרצה עובדת כך:
- JavaScript מריצה את הקוד שלך.
- libuv לוקחת משימות כבדות לרקע.
- JavaScript ממשיכה לשורה הבאה.
- libuv מודיעה ל-Event Loop כשהמשימה מסתיימת.
- ה-Event Loop מריצה את ה-callback שלך.
תחשבו על חנות פיצה.
ללא libuv, אתם עומדים ליד הדלפק ושואלים "האם האוכל שלי מוכן?" כל עשר שניות. אתם חוסמים את התור.
עם libuv, אתם מזמינים, מתיישבים ומחכים להודעה. אתם נשארים חופשיים לעשות דברים אחרים עד שהפיצה מוכנה.
סיכום:
• JavaScript execution: V8 Engine • Event Loop: libuv • File I/O: libuv • Network: libuv • Timers: libuv
libuv היא המנוע ששומר על Node.js מהיר.
