הכרות עם node.js

31 באוגוסט 2014

תגיות:
2 תגובות

בזמן הלא ארוך מאז שהשפה פותחה, נדמה ש- node.js הפכה לאחד הטרנדים הלוהטים בעולם הפיתוח והבאז סביבה לא דועך.מה יש ב- node שכל כך מושך? האם זה רק טרנד אופנתי של גיקים? האם באמת באמצעות node ניתן לעשות ניסים ונפלאות? בסדרת מאמרים זאת נכיר קצת את יכולות node וננסה לענות לכם על שאלות אלו ואחרות.

בשנת 2009 בחור בשם Ryan Dahl פיתח את node.js במטרה ליצור שרתים התומכים ביכולות אסינכרוניות  ומאפשרים ביצועים גבוהים. לטכנולוגיה הזאת הוא קרא node.js והוא בחר לממש אותה באמצעות הסינטקס של JavaScript, בין היתר, על מנת שתהיה שפה אחידה ושיתוף קוד בין שפת צד הלקוח לשפת צד השרת. מפתחי צד לקוח יוכלו בקלות לפתח אפליקציות שלמות, גם לצד השרת באמצעות שימוש באותה השפה.

אז אם ננסה להגדיר ב-3 מילים מהי node.js, נוכל להגיד שלמעשה זוהי JavaScript עבור צד השרת.

 

הבעיה

מה שמייחד שרתי אינטרנט הוא היכולת שלהם להתמודד עם מספר בקשות בו זמנית לאותו קוד. מספר גולשים למשל, מנסים להגיע בו זמנית לאותו הדף. במטרה לטפל בדרישה זאת שרתי האינטרנט משתמשים בתקשורת מבוססת threads. השרתים תומכים בריבוי threads ובדרך כלל לכל connection לשרת מוקצה thread. הבעיה בתקשורת זאת שהיא לא תמיד יעילה ודי קשה לשימוש, במיוחד שמבקשים לבצע גישה מהירה ומקבילית למשאבים ולקבצים: יכול להיות בזבוז זיכרון נרחב ויכולות להיות גם נעילות.  בעיה זאת מחמירה ככל שהעומס על השרת גבוה יותר ונדרשות יכולות גבוהות מהמפתחים לבצע אופטימיזציות ושיפור ביצועים.

 

הפתרון של node.js – גישה אסינכרונית

node.js תוקפת ישירות את בעיה זאת ומנסה לשחרר את צוואר הבקבוק מפעולות ה- I/O שחונקות את האפליקציה:
אפליקציית node.js יכולה לטפל בסוגים שונים של בקשות I/O באותו הזמן משום שברירת המחדל של כל הפונקציות והספריות היא אסינכרונית. (יש גם מספר פונקציות סינכרוניות אבל הרוב המוחלט אסינכרוני).

כל בקשות ה- I/O מהרשת מוגדרות כ- nonblocking וכל בקשות ה- I/O לקבצים מוגדרות אסינכרוניות. זאת אומרת, שהאפליקציה יכולה להמשיך לרוץ והגישה ל- I/O לא נחסמת.

באמצעות שימוש ב- node ניתן להגיע לייעול מיטבי של הזיכרון תחת עומסים כבדים. מי שמשתמש ב- node לא צריך לחשוש מ- dead-locking של processes כיוון שאף פונקציה של node לא מבצעת בצורה ישירה פעולות I/O ולכן אין נעילות.

יכולות אלו מאפשרות גם למפתחים שאינם מומחים לפתח מערכות מאד מהירות.

הטכנולוגיה בנויה כך שקל לפתח ספריות צד-שלישי המרחיבות אותה ומוסיפות לה יכולות רבות. משום כך, אנחנו רואים בשנים האחרונות גידול משמעותי בפופולריות של הטכנולוגיה ומאות ספריות עזר איכותיות המרחיבות אותה.

 

השיטה של node.js: לולאת האירועים

קונספט מרכזי ב- node.js הוא תכנות מונחה אירועים בצד השרת: הקוד מבוסס אירועים, בדומה לקוד שרץ בדפדפן.

בואו נסתכל על קטע הקוד הבא שנפוץ בהרבה אפליקציות ווב:

var result = db.query("select * from T..");
// use result

מה התוכנית עושה בזמן שהשאילתה רצה על בסיס הנתונים? ברוב המקרים פשוט מחכה לתשובה.

Ryan Dahl שפיתח את  node.js חשב שאפשר בזמן הזה לבצע עוד משימות, במקום סתם להמתין. הוא הבין שבעומסים כבדים, לא יעיל להשתמש ב- thread אחד עבור כל connection. יותר יעיל יהיה להשתמש בלולאת אירוע, event loop:

db.query("select * from T..", function (result) {
// use result
});

קוד כזה, מאפשר לתוכנית להמשיך לרוץ ולחזור ל- event loop בצורה מיידית. 
כפי שאמרנו כל הפונקציות והספריות פועלות בצורה אסינכרונית ולכן לולאת האירועים ממשיכה לרוץ לא “נתקעת”.

אגב, אם שאלתם אם עצמכם מדוע אז לא כולם משתמשים בטכניקה זאת? התשובה היא פשוטה: עד להופעתה של node.js, רוב ספריות הקוד שתמכו ב- single threaded event loops פשוט לא תמכו ב- non-blocking I/O.

אלא שכן תמכו (EventMachine, Twisted, AnyEvent) לא היו מספקים קלים לשימוש ושילוב עם ספריות נוספות והמפתחים היו מבולבלים ולכן ספריות אלו לא זכו לפופולריות רבה.

לכן, הבחירה של ריאן ב- JavaScript היתה טבעית:  שפה שמפתחים מכירים כבר, בעלת יכולות בצד הקליינט, קל לשלב אותה עם ספריות אחרות והיא תוכננה מהיסוד לשימוש עם event loop.

באמצעות node.js ריאן הרחיב את יכולות JavaScript לצד השרת ובאמצעות ספריות ההרחבה נתן לה יכולות שלא היו קיימות בה בעבר כמו קריאה וכתיבה לקבצים ועוד.

 

עקרונות node.js

ריאן מפתח השפה הגדיר במשפט אחד את מטרת פרוייקט node.js:

To provide a purely evented, non-blocking infrastructure to script highly concurrent programs

על מנת להשיג זאת, הוא הגדיר שכל שהשפה צריכה לעמוד בתנאים הבאים:

  • אף פונקציה לא תבצע קריאה ישירה ל- I/O
  • על מנת לקבל מידע מדיסק, משאב רשת או process אחר, חייבת להיות מוגדרת פונקציית callback.
  • עבודה כמה שיותר ב- low-level
  • stream everything – אף פעם אל תכריח להשתמש בבאפר
  • תמיכה מובנית בפרוטוקולים המרכזיים: TCP, DNS, HTTP
  • תמיכה מובנית בכמה שיותר יכולות HTTP
  • ה- API צריכה להיות מוכרת לכל מתכנת צד לקוח או האקר עם ניסיון ב- JavaScript
  • יכולת לרוץ על כל הפלטפורמות

 

החסרונות של node.js

למרות ש- node.js מאד פופולריות, היא עדין שפה חדשה יחסית עם API דינמי.

שנית, אם הגעתם מעולם ה- OOP ויש לכם ניסיון בשפות כמו #C או Java, תצטרכו להתרגל לכתוב קוד בשפה פונקציונלית כמו JavaScript ולהשתמש בפונקציות אסינכרוניות. זה לא תמיד הכי קל, אבל בהחלט אפשרי ומעניין.

אז איך ממשיכים?

אז למדנו למה צריך את node,js ומה העקרונות. במאמר הבא נלמד פיתוח ווב בסיסי באמצעות node.js:  איזה כלי פיתוח מאפשרים פיתוח ב-node ואיך מתקינים וניצור אתר אינטרנט פשוט.

הוסף תגובה
facebook linkedin twitter email

כתיבת תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *

2 תגובות

  1. Teemo5 באוקטובר 2014 ב 15:16

    חבל שאין השוואה ל
    WEB API
    עם
    ASYNC METHODS

    הגב
  2. שלומי אסף2 בנובמבר 2014 ב 19:04

    זה לא מדוייק ש-node.js לא תומך ב-OOP, הוא תומך חלקית.

    אמנם המודל הוא לא מודל ה-CLASS שאנחנו מכירים אלא מודל ה-PROTOTYPE אבל ישנה ירושה והיא מובנית בתוך node.js

    בנוסף, ES6 מביא איתו את הפונקציונאליות של מחלקות באופן מובנה, כלומר כתיבת CLASS באופן ישיר (class X extends y)
    יש לציין שסה"כ זה SYNTAX SUGAR ליכולות שיש היום ליצירת ירושה ע"י PROTOTYPE.

    הגב