node.js secrets

 

הסודות של node.js

למה node.js הצליח במקום בו שרתים מבוססי JS אחרים נכשלו?

 

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

 

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

מה יש בטכנולוגיה הזו שעושה אותה מעניינת כל כך למתכנתים? ולמה היא הצליחה בזמן ששרתים מבוססי Javascript אחרים מדשדשים באנונימיות או שנכשלו לגמרי?

נקודות המפתח הן ביצועים, תזמון ומיקוד בבעיה אמיתית שלא ניתן היה לפתור בעזרת שפות דינמיות אחרות בצד השרת בקלות.

 

מלחמת הדפדפנים וביצועי Javascript

 

בתחילת שנות 2000, התחילו לפתח אפליקציות AJAX מה שהגדיל את הדרישה ממנועי ה-Javascript בדפדפנים. ספריות קוד חדשות כמו YUI, Dojo ו- jQuery איפשרו למתכנתים לעשות הרבה יותר בממשק המשתמש ולכתוב אפליקציות דפדפן שמחקות אפליקציות רגילות.

 

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

 

המרוץ לשיפור ביצועי מנועי Javascript התחמם בספטמבר 2008 כשגוגל שחררה את chrome. המנוע מאחורי הדפדפן – V8 הביס את כל האחרים. דבר זה גרם למפתחי firefox, Safari, Opera וגם Internet Explorer לשפר את מנועי ה- Javascript שלהם בדפדפנים ויצר חזית חדשה במלחמות הדפדפנים.

 

באופן טכני V8 נוקט גישה קצת חדשנית כדי לשפר את הביצועים. חלק מהאובייקטים של Javascript מקומפלים ישירות לשפת מכונה לפני הרצה לפי ניתוח מוקדם של הקוד.

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

 

דפדפנים אחרים הגיבו בשיפור או כתיבה מחדש של מנועי הרצת Javascript שלהם והראו ביצועים טובים יותר מ-V8. השיפורים בללו ממשיכים לקרות גם כיום והמנוע של גוגל V8 נהנה מתרומות של המתחרים. בהשוואה למפרשים (interpreters) של שפות דינמיות אחרות על השרת כמו רובי, פייטון, PHP או Perl יש ל- Javascript מנועים עם מהדרים (Compilers) שנותנים ביצועים מאוד מהירים.

 

ריאן דאל, היוצר של Node.js בחר במנוע של V8 ל-Node. יש לכך יתרונות נוספים במנוע שרץ על השרת.

 

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

ל-Node יש עוד יתרון (גדול) בביצועים שלא קשור ישירות ל- V8 אך נגיע אליו עוד מעט.

 

השיקום של Javascript

 

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

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

למראת החסרונות המדהימים של Javascript עמוק למטה, ביסודות יש שם משהו מאוד נכון. כשאתה מקלף את הכשבות המיותרות אתה נותר עם שפה יפה ואקספרסיבית מאוד. שפה זו נמצאת בשימוש טוב בספריות AJAX רבות לניהול ועיצוב ה-DOM מה שיוצר פלטפורמה לכתיבת אפליקציות אינטראקטיביות המופצות בעזרת הרשת. Ajax הפך להיות פופולרי כי Javascript עובדת. למרבה ההפתעה היא עובדת בצורה טובה מאוד.

 

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

 

שרתים שהשתמשו ב-Javascript בעבר התקשו הרבה יותר לשכנע מתכנתים לשנות את הגישה השלילית שלהם כלפי השפה. עד שהגיעה Node.js התגברה Javascript על עיקר התדמית השלילית שלה.

 

Node.js פותר בעיה אמיתית

 

בוויקיפדיה יש השוואה די ממצה של פתרונות שרת המשתמשים ב Javascript. גם Node ברשימה אך רוב הפתרונות האחרים  שרשומים שם הרבה פחות מוכרים. השימוש במונח "פתרונות" מעניין גם הוא, מכיוון שרוב הפרוייקטים שם הם פתרונות של בעיות שנפתרו כבר על ידי שפות אחרות.

 

פייטון, ג'אווה, רובי, PHP, פרל ועוד הם עדיין חלופות טובות מאוד לרוב האפליקציות הדינמיות ברשת. הם מדברים עם בסיסי נתונים, טוחנים מספרים, מאמתים נתונים, ומעבדים תבניות. הן שפות עיליות ויש כמה פלטפורמות MVC לכל אחת מהן לבניית אפליקציות מהירה. יש המשווקים את Node.js כ- Ruby on rails הבא אך זו השוואה גרועה שמפספסת את הנקודה של מה המשמעות של Node.

 

Node לא מנסה לפתור את אותה הבעיה ש-Rails פותר והוא לא מתחרה ישירות באף אחת מהשפות האחרות או בפלטפורמות הפיתוח בתחומים שלהן. Vוא מוצלח במיוחד בפתרון סוג ספציפי של בעיות באפליקציות רשת מודרניות. מה הוא יכול לעשות שהאחרים לא?

מסתבר שמה ש-Javascript יכול לעשות הוא ההפך ממה שהוא לא יכול: קלט/פלט חוסם.

 

קלט/פלט מבוסס ארועים

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

Node כל הזמן נעה סביב לולאת הארועים, אך מה בעצם המשמעות של הדבר?

לאלו מאיתנו שהם לא מתכנתים או לא מכירים את הרעיון של לולאת הארועים, אנלוגיה יכולה לעזור.

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

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

די ברור שזו דרך לא נורמלית לפתור את הבעיה כי היא זורקת יותר עגלות וקופות ממה שהבעיה מצריכה.

שפות תכנות שחוסמות קלט/פלט מנסות לעיתים קרובות לפתור בעיות דומות על ידי הוספת threads או processes. זה יכול להיות יקר במונחי זיכרון או מחזורי מעבד.

Javascript ו- Node משתמשים בגישת לולאת הארועים ובקריאות חזרה לתקוף את הבעיה אחרת.

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

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

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

 

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

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

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

Node מספקת ספריות לא חוסמות לבסיסי נתונים ולגישה לרשת ולקבצים. מכיוון שקלט/פלט הוא לא חלק בסיסי ב Javascript לא היה צריך להרוס כלום כדי ליצור אותו.

בפרוייקטים אחרים כמו Twisted של פייטון או Event Machine של רובי היה צריך לעשות כמה מעקפים סביב מרכיבים בסיסיים בשפה כדי להגיע לתוצאות דומות.

כך בנוסף לשיפורים בביצועים ש Node מקבלת "בחינם" על ידי שימוש במנוע Javascript של V8 מודל לולאת הארועים מאפשרת ל- Node לשרת כמויות מסיביות של חיבורי רשת בו זמנית בצורה יעילה. במקרים רבים היא שואפת לתוצרות מבחני ביצועים של שרתי רשת בעלי reverse proxy כדוגמת Nginx (המבוסס אף הוא על לולאת ארועים)

 

שיתוף קוד בין הדפדפן והשרת

 

שימוש באותה שפה בשרת ובדפדפן היתה ההבטחה של הרבה שרתים מבוססי Javascript בעבר. הרעיון של "שפה אחת לשליטה בכולם" מושכת למתכנתים כצריכים לדלג משפה אחת לאחרת כל פעם שטכנולוגיה חדשה צצה.

Aptana Jaxer, אחת מהדוגמאות הידועות יותר של מימוש SSJS שנעשו לאחרונה, קיוותה למשוך מתכנתי AJAX למודל הזה. בעיקרון זה רעיון טוב. אפשר להשתמש באותן סיפריות קוד לאימות נתונים בשני הצדדים, לקרוא לפונקציות Javascript על השרת מהדפדפן ולבנות מראש HTML-DOM על השרת עם סיפריות קוד של ממשק משתמש מהדפדפן לזרוז הטעינה הראשונית של דפים.

Jaxer לא זכה לחלק קטן מתשומת הלב שלה זכה Node, בחלקו זה כנראה בגלל תזמון. לרבים Jaxer נראה כמו אימלמנטציה מחדש של ASP. בנוסף לא היה לה את השוואות הביצועים של Node והיא לא התמקדה בנושא של קלט/פלט חוסם. למראת האפשרויות המעניינות של Jaxer היא לא הגיע למסה קריטית שיוצרת קהילה חיה ובועטת.

 

מסה קריטית ל Node.js

 

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

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

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

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

 

Joyent היא חברת הבית של Node. היא המעסיקה של ריאן דאל (יוצר Node) ושל אייזיק שלטר (היוצר של npm) ואחרים שתרמו לפרוייקט. Joyent היא הבעלים של הסימן המסחרי וזכויות היוצרים של Node והשיקה לא מכבר את no.de, שרות ארוח לאפליקציות Node. זה מאפשר לNode בסיס ממומן ומשאבים להמשך פיתוח ומהווה דובר לפרוייקט בעולם המסחרי.

שחקן אחר הוא HP. קצת אחרי ש HP רכשה את Palm, מערכת ההפעלה webOS של Palm הוסיפה את Node. זה היה צעד חכם מצידה של HP והתקבל בצורה טובה מאוד על ידי קהילת webOS.

אם תחשבו על זה, Node מספקת פלטפורמת שרותים לענן, אז האם יש דרך שנוכל לעבוד ביחד? חברנו לריאן דאל מ-Node כדי לברר את זה ומסתבר ש-Node עובד מצויין על מכשיר נייד! הרבה מהקרדיט מגיע לצוות של V8 שיצרו VM מצויין ולריאן שכתב קוד יעיל שהתאים לא רק לענן אלא גם למכשירים ניידים. – Dion Almaer

 

לשים את Node על מכשירים ניידים הופך את הרעיון של Javascript על השרת על ראשו, אך בעצם למה לא? עם Node מנוע ה Javascript קטן דיו הקוד פורטבילי מספיק ומודל התכנות קל ואסינכרוני – קומבינציה מנצחת למכשירים ניידים. יכול להיות שזה ולא פלטפורמת MVC שמחקה את Rails יהיה מה שיהפוך את Node לנפוץ יותר.

 

Node הוא לא "הדבר הבא" של שום דבר

Node הוא דבר חדש, וזו הסיבה שמתכנתים מביעים בו עניין.

Node שינה את המודל המנטלי שלנו לגבי שרתים. זה לא חייב לרוץ על שרת חזק במיוחד בחדר מקורר ביחד עם שרתים של אחרים העונים למיליוני בקשות ומעבירים ג'יגה בייטים של נתונים. הוא יכול להיות בכיס שלך, מסנכרן את אנשי הקשר שלך כשהוא מוצא נקודת גישה אלחוטית. הוא יכול לשמור עותק של אפליקציית רשת לגישה מהירה יותר מהזיכרון המקומי. הוא יכול להיות שרת peer to peer. והוא יכול להיות אחד מכל מיני דברים שעוד לא חשבנו עליהם.

 

CC BY-SA 3.0