הבלוג של ארתיום
בלוג על לינוקס, תוכנה חופשית, מוזיקה, סלסה, ומה לא!
על FastCGI, על SCGI ועל בחירה של RoR ו־Django.
לאחרונה הפרוטוקול Simple CGI הופך ליותר ויותר פופולרי והופך לבחירה טבעית או אפילו ברירת מחדל של תשתיות פיתוח לאינטרנט החדשות כמו Django ו־RoR. במה מדובר? מדובר בפרוטוקול מאוד פשוט שדומה באופי שלו ל־FastCGI אבל הספציפיקציה שלו מורכבת מכמה עשרות שורות, כך גם המימוש דורש מעט קוד (רוב המימושים שראיתי לא הכילו יותר מ־100--200 שורות קוד).
למעשה הפרוטוקול הזה הוא תחליף אידיאלי ל־FastCGI עבור:
- שרתי אינטרנט קטנים שרוצים לחבר יישומים גנריים בקלות רבה, בגלל פשטות המימוש.
- יישומי אינטרנט שהמימוש של הפרוטוקול דורשת כמה עשרות עד מאה שורות קוד. בניגוד ל־FastCGI שהמימוש המלא שלו מאוד מורכב.
- אפשרות לכתוב רכיב תקשורת עם שרת אינטרנט בצורה מהירה ללא ספריה צד ג'. למעשה, בניגוד ל־FastCGI, אפילו לא קיימת ספריה סטנדרטית עבור המשימה.
- הפרוטוקל לא פחות חזק מ־FastCGI בכל הקשור לביצועים.
נראה לעין שאין שום סיבה לא להשתמש בפרוטוקל הזה על פני FastCGI, אבל במציאות יש הבדל גדול מאוד. אחרי מבט בספציפיקציה של FastCGI נתחיל:
- ב־SCGI אין הגדרה מסודרת של אופי התקשורת כל מה שכתוב זה:
The client connects to a SCGI server over a reliable stream protocol allowing transmission of 8-bit bytes
למעשה זה יכול להיות כמעט כל דבר, כאשר ב־FastCGI מוגדר : UNIX Domain socket או TCP Socket.
- אין socket ברירת מחדל כמו שקיים ב־FastCGI. stdin היכול לשמש לתקשורת בין תהליך אב לבן. זה מאפשר לשרת האינטרנט להעלות תהליכי FastCGI בעצמו. socket כזה לא מוגדר עבור SCGI.
- אין הגדרה מסודרת כיצד שרת יכול להוריד תהליך SCGI. בספציפיקציה של FastCGI הוגדר כי השרת יכול לסגור את התהיך ע"י שליחת SIGTERM.
זה נראה כנקודות מאוד פשוטות וכביכול משתמעות באופן טבעי מהמימוש, אבל זה גורם לדבר מאוד פשוט -- מימושים לוקים בחסר של scgi בשרתים השונים:
- apache-mod-scgi לא מסוגל לתקשר מעל Unix Domain Sockets שהם הבחירה הטבעית עבור תקשורת בתוך אותו מחשב. למעשה תקשורת מעל TCP/IP היא כבדה יותר ובזבזנית יותר מבחינת המשאבים.
- apache לא מוסגל להעלות תהליכים scgi בעצמו כמו שזה נעשה ב־mod_fcgi.
מימוש של lighttpd של scgi (המבוסס על mod_fastcgi) אינו תומך בהעלאת תהליכים ע"י השרת בגלל באג טיפשי שניתן לתקן אותו בשלוש שורות קוד (פתחתי באג ושלחתי טלאי).
מצד שני, האם זה באג? הרי התנהגות כזו לא מוגדרת בספציפיקציות וספק אם קיימים יישומים web (מלבד CppCMS) שיידעו לקבל 0 כ־socket סטנדרטי שניתן לעשות לו accept כמו שזה נעשה ב־FastCGI.
למעשה מאחורי scgi עמד רעיון מאוד טוב: להחליף פרוטוקול מורכב שהמימוש שלו די מסובך בפרוטורול מאוד פשוט העושה את אותה העבודה בדיוק. רק הבעיה היא, שאפשר היה לעשות "קצת יותר" על מנת לעשות אותו מלא באמת. למעשה, זה מבחין בין תכנון פרוטוקול טוב לבין תכנון גרוע שנעשה בצורה חפוזה.
אז האם הבחירה של RoR ואחרים ב־scgi כברירת מחדל היא אכן בחירה מושכלת?
הוסף תגובה:
חובה לאפשר JavaScript כדי להגיב.