נושא ה Scalability הוא פופולרי-במיוחד בכמה השנים האחרונות.
לאחרונה עברתי על עשרות קורות חיים של מועמדים - ובכמעט כולם צוינו מושגים כמו "High Scalability", או "Big Data", "NoSQL", "Hadoop" - וכו'. כנראה שכל מי שעבד במערכת עם הרבה transcriptions per seconds או נפחים גדולים של נתונים - סיפר על כך בהרחבה, ומי שלא - התאמץ להראות איזו זיקה. זה "המשחק" היום, ונראה לי שהייתי עושה בעצמי את אותו הדבר בדיוק!
בפוסט הזה אני רוצה לספר על תהליך של Hyper-Scaling שאנו עוברים בחברת Gett - וכיצד הוא משפיע על עבודת הארכיטקטורה.
אני רוצה להזכיר שהמונח "Scalability", מתייחס בהנדסת תוכנה לשני סוגים של אתגרים:
אנו מגיעים ל Scale כאשר יש לנו כמות משאבים (למשל: שרתים) מסוימת, וכל שרת מבצע עבודה בקצב מסוים.
באופן דומה, גם בגדילה של גוף פיתוח - המפתח האחרון שנוסף נוטה להיות (בממוצע!) פחות יעיל מקודמו:
--
לאחרונה עברתי על עשרות קורות חיים של מועמדים - ובכמעט כולם צוינו מושגים כמו "High Scalability", או "Big Data", "NoSQL", "Hadoop" - וכו'. כנראה שכל מי שעבד במערכת עם הרבה transcriptions per seconds או נפחים גדולים של נתונים - סיפר על כך בהרחבה, ומי שלא - התאמץ להראות איזו זיקה. זה "המשחק" היום, ונראה לי שהייתי עושה בעצמי את אותו הדבר בדיוק!
בפוסט הזה אני רוצה לספר על תהליך של Hyper-Scaling שאנו עוברים בחברת Gett - וכיצד הוא משפיע על עבודת הארכיטקטורה.
No Scale |
אני רוצה להזכיר שהמונח "Scalability", מתייחס בהנדסת תוכנה לשני סוגים של אתגרים:
- Software Scalability - התמודדות עם יותר משתמשים, יותר פעילות, יותר נתונים.
- Development Scalability - היכולת להתנהל עם צוות פיתוח גדול יותר.
ב Gett יש לנו Software Scale מסוים, שהוא לא קטן - אבל גם לא ענק. ככה וככה נתונים, ככה וככה פעולות בשנייה.
ההתמודדות העכשווית שלנו היא דווקא יותר עם Development Scalability, שכמו שאנסה להראות במהלך הפוסט - יש לה דמיון לא-קטן ל Software Scalability.
לפני כחצי שנה, כשהגעתי ל Gett היו בצוות צד-השרת כשישה מתכנתים. הגעתי מעט לאחר גיוס ענק של 150M$ שהחברה ביצעה. עם הגיוס, החברה החליטה להגדיל משמעותית את קבוצת ה R&D - בכדי לקבל משמעותית יותר תפוקה. בעת כתיבת הפוסט יש לנו כבר עשרים וחמישה (!!!) מתכנתי צד-השרת - ואנחנו עוד מגייסים.
את הכלל של "לא להגדיל גוף פיתוח ביותר מ 50% בשנה" - שברנו כבר מזמן... מה עושים עכשיו? ואיך מתמודדים עם זה מצד הארכיטקטורה?
את הכלל של "לא להגדיל גוף פיתוח ביותר מ 50% בשנה" - שברנו כבר מזמן... מה עושים עכשיו? ואיך מתמודדים עם זה מצד הארכיטקטורה?
ההקבלה בין Scale של תוכנה ו Scale של קבוצות-פיתוח
נוסחה מקובלת בעולם ה Software Scale היא זו:
אנו מגיעים ל Scale כאשר יש לנו כמות משאבים (למשל: שרתים) מסוימת, וכל שרת מבצע עבודה בקצב מסוים.
גדילה ב Scale, כלומר: Scaling - מתבצעת ע"י הוספת שרתים או לחלופין ע"י שיפור הביצועים של כל מחשב בודד במערכת.
ככל שהמערכת גדלה - סביר שנחווה מצב בו כל מחשב נוסף שאנו מוסיפים הוא פחות יעיל מקודמו. מדוע? מכיוון ש:
- פעולות על כמות גדולה יותר של נתונים - אורכות יותר זמן. למשל: אינדקסים בבסיס נתונים רלציוני, הפחתת הרציפות בדיסק, caches פחות יעילים או סתם פעולות joins גדולות יותר (merge על work set גדול יותר).
- יותר תקשורת שנדרשת בין המחשבים השונים במערכת. יש הבדל בין הודעות עדכון שנשלחות ל 6 מחשבים - וכאלו שנשלחות ל 25 מחשבים. פעם נתקלתי במערכת שהוספה של מחשבים למערכת, מעל 16 מחשבים, כבר לא הגדילה את ה scale - בגלל ריבוי של הודעות כאלו.
- כמות הקוד שלא ניתן למקבל (parallelism) באופן טבעי תגדל, ולא תקטן - אלא אם הייתה השקעה משמעותית בצמצום קוד שכזה.
- חוסרי יעילות שונים - שצצים במערכת באקראיות טבעית.
- כל עבודה רוחבית במערכת (למשל: Refracting גדול), הופכים להיות קשים וארוכים פי כמה - כאשר כמות הקוד גדולה יותר.
- יותר תקשורת וסנכרון נדרשת בין המפתחים בקבוצה. אם פעם היה מספיק להרים את הראש מבהייה במסך - בכדי ליצור קשר עם מתכנת שמכיר היטב היבט מסוים של המערכת, היום כבר צריך לקום מהמקום, לחפש - ולעתים לגלות שצריך לדבר עם כמה אנשים בכדי לקבל תמונה מלאה.
- תמונות-העולם של המפתחים בארגון מתבזרות במהירות: בניגוד לצוות שהיה לו זמן להתגבש במשך תקופה ארוכה - כעת יש זרימה של אנשים חדשים, שכל אחד רגיל לשיטות שונות וגישות שונות.
הגישות הללו, עבור כל אחד, "הוכיחו את עצמן מעל ספק סביר - בעבר". אמת. אבל מה עושים כאשר הגישות הפוכות זו לזו? האם ORM הוא טוב להכל, טוב רק לקונפיגורציה, או "רעה-חולה שיש להסיר מהמערכת בהקדם האפשרי!"? - יותר ידיים עובדות => יותר קוד => מערכת מורכבת יותר. כל שינוי במערכת מורכבת יותר - אורך יותר זמן בעצמו (מגמה לחוסר יעילות מובנה).
- נוצרים יותר צווארי בקבוק ("רק משה מכיר את הקוד הזה") - שהולכים ומקשים יותר ויותר על התקדמות הפיתוח.
- יותר ישיבות, יותר המוניות, יותר אנשים שיש להכיר ולהתרגל לעבוד איתם - חוסרי יעילות שונים, שצצים במערכת באקראיות כל-כך טבעית.
ההשקעה ב Development Scale בפיתוח אמנם עוסקת במידה רבה בגיוס עובדים ("Capacity"), אבל לא פחות מכך - בשיפור היעילות של כל עובד ("Performance"). תהליכי ה Continuous Integration (ליתר דיוק: on-going integration) - מוגדרים מחדש, אנו משקיעים יותר בשיתוף הידע - ופישוט שלו, וכאן יש לצוות הארכיטקטים תפקיד חשוב.
אנו חותרים ל Continuous Delivery (הפעם: באמת) - בכדי לשפר את יכולת התגובה לתקלות במערכת, וכדי לעשות אותה יציבה יותר. באופן פרדוקסלי משהו, הניסיון בתעשייה מראה שדווקא העלאת תכיפות ה deployments מגדיל את יציבות המערכת - בטווח הבינוני-ארוך. יותר deploys = יותר "שבירות", אבל אז גם יותר לקחים, יותר מנגנוני-התאוששות ובקרה, ויותר אוטומציה. כל עוד אין מנגנון ארגוני שמותיר "לעצור את הקצב, ולצמצם את קצב ה deploys" - האנרגיות ינותבו לשיפור המערכת, ומנגנוני הייצוב שלה.
--
ב Software Scale, יש את השאיפה התמידית ל Linear Scalability: האידאל שלפיו הוספה של כל מכונה למערכת, תתרום את החלק היחסי שלה. למשל: הכפלת כמות השרתים - תכפיל את הספק העבודה (למשל: כמות בקשות בשנייה).
לא ממש Linear Scaling: ככל שמספר הבקשות עולה - יש להוסיף חלק יחסי גדול יותר של שרתים בכדי לענות על הביקוש. יש במערכת הזו צווארי בקבוק מסוימים ל scalability. |
בקבוצת ה R&D כולנו מבינים שככל שהמערכת גדלה - היעילות של המתכנים הולכת וקטנה. אין לנו שאיפות ל Linear Development Scalability. אנחנו גם מכירים במגבלות המקבילות האנושית ("תשע נשים לא יכולות ללדת ילד בחודש אחד").
בשונה מאיתנו ל Business דווקא יש ציפיות ל Linear Scalability - מפורשות יותר או פחות.
"פי-2 אנשי support עונים לפי-1.9 קריאות במוקד?" - הם מספרים, "כן... אנחנו מבינים שהנדסה זה קצת יותר מורכב. הגדלנו את הפיתוח פי 4, ואי-אפשר לקבל פי-4 פיצ'רים - אבל גם אי אפשר כבר לצפות לפחות לפי-3 יותר פיצ'רים, או לקבל אותם לפחות פי-3 יותר מהר?"
הלחץ מצד הביזנס הוא אולי משני, אבל הוא משפיע - וגורם לנו להתייעל יותר בכל הנוגע ל Development Scalability של הפיתוח. בעיקר ע"י צמצום חוסר-היעילות שהמערכת יוצרת למפתח הבודד.
--
ב Software Scale, יש "קסם" שיכול לסייע למערכת לצמוח ב Scale שהוא יותר מלינארי: מצב בו פי-2 שרתים, משרתים יותר מפי-2 משתמשים. כיצד זה קורה? יש כמה דרכים, אבל ה"קסם" הנפוץ ביותר הוא Cache (או memoization - בגרסה התאורטית שלו).
כאשר אנו יכולים לבצע חישוב מורכב רק פעם ב 5 דקות, ואז להפיץ את התוצאות לעוד ועוד משתמשים - כמות גדולה אפילו יותר של משתמשים תגדיל את הלחץ רק על ערוץ ההפצה (CDN?) - ולא על יצירת התוכן (החישוב).
ככל שנתכנן את המערכת שלנו בצורה בה ניתן יהיה להשתמש יותר ויותר ב Caches שכאלו - נשפר את ה Scalability של המערכת. תכנון שכזה כולל, הרבה פעמים - משא ומתן עם אנשי הביזנס ("תקבלו את זה מעודכן פעם בשעה - לא כל הזמן").
(פתרונות אחרים כוללים העברת עבודה ל Clients, או צמצום העבודה לקצב קטן מבו עולה ה scale, למשל: ביצוע חישוב על 500 משתמשי-מדגם, ללא קשר למספר כלל-המשתמשים במערכת).
ב Development Scaling יש גם כמה "קסמים" שכאלו. הבולט בהם - הוא code re-usability: היכולת להשתמש בקוד שנכתב בעבר - עבור פיצ'ר חדש.
פתרון שונה-דומה הוא Generalization: כתיבת קוד כללי יותר - שיכול לשרת מטרות דומות, אך שונות.
הקסמים האלו - הם חמקמקים ביותר!
הם באמת לפעמים "עושים את הקסם" - אבל פעמים אחרות "יוצא מהם כל האוויר" ברגע האמת: אנו משקיעים עוד זמן ועבודה בקוד כללי יותר / קוד המתוכנן לשימוש חוזר - אבל אז השימוש החוזר פשוט לא מתאים. אם השקענו בקוד כללי - ואין לו שימוש, אנו נשארים עם קוד יקר יותר, מסובך יותר, ועם הצורך עדיין לספק פתרון לפיצ'ר השני (או, חס וחלילה: לאנוס את הפיצ'ר השני להיות משהו אחר - בכדי להתאים לקוד שכבר קיים).
מהנדסים צעירים, ואולי אף מהנדסים בכלל - נוטים לבצע הערכת יתר (גסה?) ליכולת שלהם לייצר קוד יעיל לשימוש חוזר / קוד כללי יעיל. משם נוצר הכלל You Ain't Gonna Need It (בקיצור: YAGNI) המציע פשוט לא לנסות לחזות מקרים אלו מראש, אלא לעשות Refactoring לקוד כללי רק ברגע שהוכח הצורך - מעל ספק סביר.
בכל מקרה: שימוש חוזר בקוד והכללה, גם אם נעשים בדיעבד - הם כלים חשובים מאוד לשיפור ה Development Scalability.
אולי אתם מאוכזבים מעט מהפוסט: יש בו הרבה דיבורים כללים, ואין בו Hadoop, HPC או Big Data משום צורה!
אני אנסה לתמצת:
הפיתוח של Gett עובר כרגע תהליך של Development Hyper-Scaling. יש גם בעיות של Software-Scaling - אבל הן (עדיין) פחות מאתגרות - אולי אזכיר לקחים משם בפוסט אחר.
הארכיטקטורה, או תוכנית-העל שלנו להתמודד עם בעיות ה Development Hyper Scaling הן כאלו:
אני מודע לכך שעדיין אין פה Design Patterns הנדסיים משמעותיים (אולי מלבד MSA) - אבל זה מה שעובד, ואנו עושים את מה שעובד - ולא רק מה שמתאים לציפיה מסוימת (ארכיטקטורה = "תרשימים של ריבועים"). סורי! :)
זהו... מקווה שנהניתם, ואולי אף השכלתם. כרגיל - אשמח לתגובות.
שיהיה לנו בהצלחה!
"פי-2 אנשי support עונים לפי-1.9 קריאות במוקד?" - הם מספרים, "כן... אנחנו מבינים שהנדסה זה קצת יותר מורכב. הגדלנו את הפיתוח פי 4, ואי-אפשר לקבל פי-4 פיצ'רים - אבל גם אי אפשר כבר לצפות לפחות לפי-3 יותר פיצ'רים, או לקבל אותם לפחות פי-3 יותר מהר?"
הלחץ מצד הביזנס הוא אולי משני, אבל הוא משפיע - וגורם לנו להתייעל יותר בכל הנוגע ל Development Scalability של הפיתוח. בעיקר ע"י צמצום חוסר-היעילות שהמערכת יוצרת למפתח הבודד.
--
ב Software Scale, יש "קסם" שיכול לסייע למערכת לצמוח ב Scale שהוא יותר מלינארי: מצב בו פי-2 שרתים, משרתים יותר מפי-2 משתמשים. כיצד זה קורה? יש כמה דרכים, אבל ה"קסם" הנפוץ ביותר הוא Cache (או memoization - בגרסה התאורטית שלו).
כאשר אנו יכולים לבצע חישוב מורכב רק פעם ב 5 דקות, ואז להפיץ את התוצאות לעוד ועוד משתמשים - כמות גדולה אפילו יותר של משתמשים תגדיל את הלחץ רק על ערוץ ההפצה (CDN?) - ולא על יצירת התוכן (החישוב).
ככל שנתכנן את המערכת שלנו בצורה בה ניתן יהיה להשתמש יותר ויותר ב Caches שכאלו - נשפר את ה Scalability של המערכת. תכנון שכזה כולל, הרבה פעמים - משא ומתן עם אנשי הביזנס ("תקבלו את זה מעודכן פעם בשעה - לא כל הזמן").
(פתרונות אחרים כוללים העברת עבודה ל Clients, או צמצום העבודה לקצב קטן מבו עולה ה scale, למשל: ביצוע חישוב על 500 משתמשי-מדגם, ללא קשר למספר כלל-המשתמשים במערכת).
Scaling שהוא טוב מ Linear-Scaling: הוספת שרת למערכת - מוסיפה יכולת לספק קצת יותר משתמשים מחלקו במערכת. |
ב Development Scaling יש גם כמה "קסמים" שכאלו. הבולט בהם - הוא code re-usability: היכולת להשתמש בקוד שנכתב בעבר - עבור פיצ'ר חדש.
פתרון שונה-דומה הוא Generalization: כתיבת קוד כללי יותר - שיכול לשרת מטרות דומות, אך שונות.
הקסמים האלו - הם חמקמקים ביותר!
הם באמת לפעמים "עושים את הקסם" - אבל פעמים אחרות "יוצא מהם כל האוויר" ברגע האמת: אנו משקיעים עוד זמן ועבודה בקוד כללי יותר / קוד המתוכנן לשימוש חוזר - אבל אז השימוש החוזר פשוט לא מתאים. אם השקענו בקוד כללי - ואין לו שימוש, אנו נשארים עם קוד יקר יותר, מסובך יותר, ועם הצורך עדיין לספק פתרון לפיצ'ר השני (או, חס וחלילה: לאנוס את הפיצ'ר השני להיות משהו אחר - בכדי להתאים לקוד שכבר קיים).
מהנדסים צעירים, ואולי אף מהנדסים בכלל - נוטים לבצע הערכת יתר (גסה?) ליכולת שלהם לייצר קוד יעיל לשימוש חוזר / קוד כללי יעיל. משם נוצר הכלל You Ain't Gonna Need It (בקיצור: YAGNI) המציע פשוט לא לנסות לחזות מקרים אלו מראש, אלא לעשות Refactoring לקוד כללי רק ברגע שהוכח הצורך - מעל ספק סביר.
בכל מקרה: שימוש חוזר בקוד והכללה, גם אם נעשים בדיעבד - הם כלים חשובים מאוד לשיפור ה Development Scalability.
אז מה עם ארכיטקטורה ל Hyper-Scaling?!
אולי אתם מאוכזבים מעט מהפוסט: יש בו הרבה דיבורים כללים, ואין בו Hadoop, HPC או Big Data משום צורה!
אני אנסה לתמצת:
הפיתוח של Gett עובר כרגע תהליך של Development Hyper-Scaling. יש גם בעיות של Software-Scaling - אבל הן (עדיין) פחות מאתגרות - אולי אזכיר לקחים משם בפוסט אחר.
הארכיטקטורה, או תוכנית-העל שלנו להתמודד עם בעיות ה Development Hyper Scaling הן כאלו:
- בראש ובראשונה - מעבר ל Micro-Services: הפיכת מערכת אחת מורכבת - לכמה מערכות קטנות יותר, ומורכבות פחות. המעבר הוא אינטנסיבי, אבל הוא מאפשר להבין ביתר קלות את כלל המערכת - ולדעת להיכן לצלול בעת הצורך. כמו כן - הוא מצמצם במידה רבה את הצורך בתקשורת מרובה, לטובת תקשורת בסיסית יותר וממוקדת יותר, למשל: סך האחריויות של כל שירות, וה APIs שלו - שמוגדרים היטב (אנחנו משתמשים ב Swagger לתיעוד - כלי שמשרת אותנו היטב).
את השימוש ב MSA להתמודדות עם Development Hyper-Scaling לא המצאנו בעצמנו: למדנו מ case-studies על חברות שעמדו באתגר דומה (למשל: אמזון). - שימוש-חוזר בקוד, הוא רעיון שקשה לממש (מעבר לפונקציה פה ושם). דווקא Micro-services, בכך שאנו מגדירים שירותים עם שימוש עסקי ברור, ו APIs מוגדרים היטב - מסייעים לנו ליצור יחידות גדולות של קוד שמתאימות לשימוש-חוזר. כבר בחצי-שנה האחרונה, היו לנו כמה הצלחות יפות.
- אנו עוסקים בצורה פרואקטיבית בארגון בשיתוף ידע על חלקי המערכת השונים, האחריויות שלהם, וה flows העיקריים במערכת. לא עובר כמעט שבוע שאני לא עושה session שכזה, לצוות כלשהו בפיתוח - ואני לא היחידי. עוד פעם ועוד פעם - עד שלכולם כבר יימאס (אנחנו עוד רחוקים משם...).
שמות פשוטים, מטפורות טובות, וסיפורים קליטים - הם מרכיב עקרי בבניית והפצת הידע. - צוות הארכיטקטים לוקח תפקיד קצת יותר ריכוזי מהרגיל (אולי: יותר מהאידאל האישי שלי?!) בהגדרת superflows חדשים במערכת. כן! אנחנו רוצים לעבוד יותר agile ולתת לאנשים יותר ויותר אחריות והשפעה, אבל בנקודת הזמן הזו - תוצאות טובות יותר מושגות כאשר לפחות את ה flows העיקרים - מוגדרים מרכזית ע"י הארכיטקטים.
כאשר מפתחים עושים שינויים ושיפורים ב flows - זו סיבה לשמחה (אלא אם בכך הם סותרים עקרונות או flows אחרים במערכת). - אנו מנסים לקדם בקוד כמה עקרונות:
- קידום תרבות של הצגת פתרונות - ולא רק בעיות (בכל ה R&D).
- קוד פשוט להבנה - עדיף יותר על פני קוד קצר או מתוחכם. אם אתם קוראים של הבלוג זמן רב, אתם אולי יודעים שזו הנטייה הטבעית שלי - אבל זה לא הסטנדרט הברור של ריילס (שם עקרונות של קוד קצר ו DRY - מושרשים עמוק בקהילה).
- יותר כלי monitoring ו supportability עבור הפיתוח. בכתיבה של כל פיצ'ר - לחשוב איזו השקעה תהיה משתלמת כאשר לפיצ'ר הזה תהיה בעיה ב production. כלי supportability יכולים להציג חווית שימוש עלובה למדי - כל עוד הם עוזרים.
- הכנסה של אוטומציה / בדיקות יחידה / בדיקות-API / בדיקות-אינטגרציה. בכל ארגון שראיתי בעשור האחרון זו הייתה המגמה - אבל אנחנו עכשיו צריכים את זה יותר.
אני מודע לכך שעדיין אין פה Design Patterns הנדסיים משמעותיים (אולי מלבד MSA) - אבל זה מה שעובד, ואנו עושים את מה שעובד - ולא רק מה שמתאים לציפיה מסוימת (ארכיטקטורה = "תרשימים של ריבועים"). סורי! :)
זהו... מקווה שנהניתם, ואולי אף השכלתם. כרגיל - אשמח לתגובות.
שיהיה לנו בהצלחה!
מעניין!
השבמחקאשמח לשמוע האם עם כניסתך הנחלת שינויים מהותיים ואיך צוות הפיתוח קיבל את זה? במיוחד הוותיקים...
היי אנונימי,
מחקלפני שהגעתי, הוותיקים כבר התחילו במעבר למיקרו-שירותים / SOA.
כשנכנסתי לא היה מהפך, אלא יותר שיפור הכיוון: שירותים קטנים יותר, מוגדרים טוב יותר, פיזור גם של ה UI לשירותים השונים, הגברת הקצב בפירוק לשירותים - וכו'. כלומר: דיי לקחתי את הכיוון שכבר היה והמשכתי אותו, וכיווננתי אותו.
כמובן שהיו גם חילוקי-דעות, אבל עצם כך שזה התחבר למאצץ קודם - זה הקל מאוד.
ליאור
קודם כל זה היה פוסט ממש מעניין!
השבמחקיש לי שאלה שקצת יותר קשורה לעבודה עם MSA - עד כמה השינויים של הapi בין השרותים תכופים, כלומר, מה פחות או יותר היחס אצלכם בין שינויים בתוך שרותים יחסית לשינויים בapi שהממשקים חושפים?
היי אנונימי,
מחקאנסה לענות, אם כי הניסיון שלנו איננו ארוך: אני "רצים" עם מיקרו-שירותים מעט יותר מחצי שנה - ורוב השירותים עדיין בשלבי ההתבגרות שלהם.
אנחנו זקוקים להרבה תוספות ל APIs של השירותים: החל בפרמטר - ועד endpoints נוספים. השינויים שלא דורשים שינוי ב API בכלל - הם לרוב תיקוני באגים, שיפורי ביצועים, או שיפורי UI.
מה שכן קורה הוא ש APIs מסויימים נשארים יציבים במטרתם - ורק מוספים להם עוד פרמטרים, שיעזרו לטפל במקרי קצה.
סה"כ הייתי אומר שקרוב לחצי מהתוספות שאנו מוסיפים לשירותים - גוררות שינויי API. התוספות שלא הן לרוב שיפורים ל UI או refactorings פנימיים.
נ.ב. 1 - ה UI שלנו לא עובד מול Public APIs (טבעי יותר בריילס + בכדי להתקדם מהר יותר).
נ.ב. 2 - שינויי ה APIs הם backward compatible - אחרת אנו מוסיפים מספר גרסה חדש ל API.
מקווה שעניתי על השאלה,
ליאור
תודה על המענה המהיר.
מחקאני לא בטוח למה אתה מתכוון שאתם לא עובדים מול public apis, אתה יכול טיפה לפרט בבקשה?
היי אנונימי, התייחסתי רק ל UI:
מחקאנו עובדים בריילס, שם רינדור ה HTML נעשה בצד השרת. לו זה היה javaScript based UI - אז בכדי לבצע פעולות (יצירת אובייקט, עדכון אובייקט, וכו') - היה עלינו לפנות מהדפדפן לשרת דרך API מוגדרים היטב.
ברגע שעובדים בריילס פעולת לחיצה על כפתור (למשל: "update"), גורמת לפעולת "form submit" בדפדפן - שקורא ב HTTP POST ל endpoint שנוצר ע"י ה framework של ריילס - ולא ע"י מתכנת. משם מופעל קוד צד-שרת שמפעיל את הלוגיקה העסקית.
זה אומר שה endpoint שריילס יצר עבור ה UI איננו קריא, או נוח כ"כ לשימוש - ואינו מובטח להיות backward compatible במידה ועושים שינויים ב UI. זה מאוד נוח ומקצר תהליכים של פיתוח UI - אבל זה אומר שה "APIs של ה UI" - מנוהלים אוטומטית ע"י ה framework ולכן אנו מתייחסים אליהם כ API שאינו Public.
זה נושא קצת מבלבל... מקווה שהצלחתי להסביר.
לסקיילינג (כפי שאתה מתאר פה) בכלכלה קוראים תפוקה שולית פוחתת. מוזר שהיה צורך להמציא לזה פה שם אחר.
השבמחקצודק. תפוקה שולית פוחתת הוא המונח, אם כי כמו שהראתי - לפעמים ניתן להגיע לתפוקה (או סקייליניג) שולית גוברת - בעיקר בתוכנה, פחות בארגוני-פיתוח.
מחקמעניין כתמיד
השבמחקתודה!
מחקליאור, תמיד כיף לקרוא את הפוסטים שלך!
השבמחקכיף לראות שאתה נהנה מהמקצוע שלך ומפיץ את הידע שלך! שיהיה לך הרבה הצלחה ותמשיך לכתוב:)
היי ליאור, בזמנו היו הרבה דיונים פה על הנושא של ה-microservices ונשאלת הרבה שאלות.
השבמחקהאם לדעתך המתודולגיה הבאה היא לגיטימית:
1. השירותים נמצאים בפרוייקט משותף כדי לחסוך ב-deolyment ולהקל על ניהול הפיתוח.
2. לשנות פונקציונליות כדי להימנע ממצב של צורך בפניה לשני שירותים בפעולה אחת.
3. במקרה שפעולה אטומית בצד השרת, מחייבת שימוש בפונקציונליות של שירות אחר, הדבר ייעשה באמצעות dll משותף או במקרה של פעולה קטנה אפילו ישוכפל קוד.
4. לא קשור דווקא ל-microservices אבל ה-service layer לדעתך צריך להיות נקי מקוד (כדי לאפשר החלפה קלילה של framework) או לכלול את הלוגיקה של שכבת השירות (נניח מיפוי dto ל-domain model) כדי לא לייצר אובר אבסרטקציה ועבודה בצורה לא סטנדרטית.
היי אנונימי,
מחקכן. אני חושב שזה לגיטימי - חשוב להתאים את הארכיטקטורה לצורך הייחודי של הביזנס / מערכת שלנו - ולא לזה של טוויטר / נטפליס / וואטאבר.
ספציפית:
1. אם אתה עושה deployment לכל בסיס הקוד ביחד - זה סוג של "לא לעשות MSA". הצורך ב deploy בלתי-תלוי הוא המניע מס 1 לאימוץ MSA. מניע מספר 2 - הוא כנראה development scalability.
אם אתם לא זקוקים ל deploy של חלקי-מערכת - לכו על זה.
2. השאלה העקרית היא מה הייתרונות שבכך - והאם הם שווים את החסרונות? אילוץ של "קריאה יחידה לשירות אחר בפעולה" עשויה לגרום לאנשים לבצע שרשרת קריאות ("רכבת קריאות") שלא היו הגיוניות במצב אחר - בכדי להצמד לכלל הזה.
3. ניתן ומקובל לשתף פיסות קטנות של קוד בין שירותים בכדי לחסוך קריאות בין-שירותים. האם הפעולות האטומיות שאתה מדבר עליהן לא כוללות נתונים? שכפול (מדוד) שלנתונים הוא גם מקובל - אבל חשוב מאוד שלכל ערך יהיה בדיוק עותק אחד שהוא "הכי מעודכן במערכת" / "העותק הנכון".
4. ב MSA השימוש ב Layers הוא משני - ויכול להיות שונה מכל שירות לשירות. "החלפה קלילה של Framework" - נשמע לי דבר והיפוכו. רעיון מרכזי ב MSA הוא לייצר שירותים קטנים - שיאפשרו לכל שירות להשקיע קצת פחות בסדר: פחות שכבות, פחות frameworks, ופחות תכנון לעתיד. קריטריון חשוב לשירות הוא היכולת לזרוק אותו בכל רגע - ולכתוב את השירות מחדש.
בקיצור: הכללים שאתה מציג סוטים מאוד מהמקובל בעולם ה MSA - וזה בסדר גמור (!!!).
השאלה החשובה לדעתי היא לא "האם אלו כללי MSA לגיטימיים", אלא האם הכללים הללו משרתים בצורה טובה את צורכי המערכת *שלך*.
מקווה שסייעתי,
ליאור
תודה רבה ליאור. כמעט מכל משפט שאמרת יש לי הרבה מה ללמוד....
מחקמעניין מאד, תודה שאתה משתף אותנו בניסיון והחויות שלך במקום.
השבמחקבזמנו (לפני כשנתיים) התחלנו ב-ClickTale תהליך דומה של Scaling ברמת הפיתוח והמפתחים והכיון שחתרנו אליו היה די דומה.
סרטון שהוצג למפתחים שלנו בזמנו כדי להמחיש את החזון והכיון, הסרטון (מחולק ל-2) עוצב על ידי Spotify כדי להציג את תרבות הפיתוח בחברה:
https://www.youtube.com/watch?v=Mpsn3WaI_4k&list=PL8kOOe_U2cOQQ8zPDFRbecezdjT0S4znF
https://www.youtube.com/watch?v=X3rGdmoTjDc&list=PL8kOOe_U2cOQQ8zPDFRbecezdjT0S4znF
תודה, אריאל!
מחקמעניין ומחכים, תודה רבה ליאור!
השבמחקתודה, גיליתי היום את הבלוג שלך וזה ללא ספק תגלית חשובה!!!
השבמחקשאלה עקרונית בקשר ל MSA, איך אתם (או בכלל ממה שמוכר לך) מתמודדים עם הפער שיש בדרך כלל בין ידע של מתכנת ב UI לעומת הידע ב SERVER SIDE ?
ממה שאני מכיר בדרך כלל אתה מומחה או בזה או בזה
היי יניב,
השבמחקה UI של השרותים הוא UI אדמיניסטרטיבי, פשוט ברובו. מתכנתי צד-השרת מתמודדים איתו ללא קושי מיוחד.
זכור לי מקרה אחד שבו באמת הייתה מורכבות מסויימת - ואז נועצו במומחה צד-לקוח.
בקיצור: מתכנתי צד-השרת עושים גם את צד הלקוח, מה שנקרא מתכנתי Full Stack. אם הם לא היו מסוגלים לעשות זאת - היה נכון לשקול תצורת עבודה אחרת. למשל את אפליקציית המובייל (UI שדורש מומחיות רבה + אינו וובי / נארז אחרת) - מפתח צוות אחר, והחלוקה למיקרו שירותים לא משפיעה על מבנה האפליקציה.