המעבר ממונוליטי ל-Microservices

כל מי שנמצא ברמה ניהולית של IT (מנמ"ר/CTO/CIO וכו') בוודאי מכיר את הדבר הבא: חברה מעוניינת לפתח מוצר גדול, "הדבר הבא" בתחום שלהם. מתקיימות מספר ישיבות עם גורמים שונים בחברה ותוך כדי כותבים מפרט ארוך מה הולך להיות בתוך המוצר, במה הולכים לתמוך בתוך המוצר וכו' וכו'.

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

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

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

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

פרויקט גדול מורכב מחלקים רבים שצריך לכתוב. בשיטה המונוליטית כל החלקים משתלבים אחד עם השני (Linking) כך שאי אפשר לשלב קוד בחופשיות של מפתחים שונים. צריך לבדוק כל חלק שמבצעים לו Commit שהוא לא שובר חלקים אחרים במוצר. בשיטת ה-Microservices (אני אקרא לזה מ"ש במשך פוסט זה) עושים דברים בשיטה הפוכה: כל חלק שצריך לכתוב, יכתב באופן עצמאי לחלוטין, הוא יכול להיות כתוב בשפה אחרות או עם פלטפורמה/Framework שונה מחלקים אחרים – כל עוד לאותו חלק יהיה ממשק RESTful API שאליו נוכל לשלוח פרמטרים (דרך YAML, JSON וכו') ונוכל לקבל נתונים בחזרה מאותו חלק בפורמט שנרצה.

וכך, בשיטה זו הצוותים השונים עובדים בצורה עצמאית לחלוטין והדבר היחיד שהם צריכים לשמור, זה פורמט API שמוסכם בין כל הצוותים ומתועד. זו בדיוק ההזדמנות גם להשתמש בטכנולוגיות חדשות, או לקחת מפתחים מבחוץ שיודעים לבנות לדוגמא UI בכלים מודרניים, אפשר להשתמש בכלי CI/CD לבדוק ולקמפל כל חלק באופן עצמאי, לכתוב טסטים ולבצע Stress testing לכל חלק.

לאחר שהחלקים השונים נכתבו (או במהלכם) – אנחנו נשתמש במערכת אורקסטרציה לקונטיינרים (כמו Kubernetes/OpenShift) בכדי להריץ כל חלק בקונטיינר/POD והתקשורת בין החלקים תהיה דרך HTTP/HTTPS ודרך פרוטוקולים אלו נשתמש ב-API כך שכל חלק יוכל לדבר עם חלקים אחרים.

במתודה המונוליטית, כשאנחנו צריכים לבצע Scaling, אנחנו בעצם נשכפל מכונות VM ונגדיר את ה-Load Balancer שידע להפנות פניות למכונות ה-VM השונות. הבעיה המהותית בשיטה הזו, היא שאנחנו משתמשים במשאבים רבים כשברוב המקרים רק חלק מסויים או חלקים מסויימים צריכים את ה-Scaling ושאר החלקים רק תופסים זכרון מבלי לעשות כמעט כלום. במתודת ה-מ"ש לעומת זאת, אנחנו יכולים לבצע Scaling דינמי לאותו חלק שמשאביו נגמרים וה-Scaling עצמו יבוצע תוך שניות בודדות (בניגוד להקמת VM נוסף), כך שברוב המקרים, כמות המשאבים שנצטרך לבצע Scaling – תהיה נמוכה בהרבה בהשוואה למתודות הרצה של אפליקציות מונוליטיות (הוספת עוד ועוד מכונות VM).

בכל הקשור לשדרוגי חלקים, HA, אחסון ושליפת נתונים, תקשורת ואבטחה – עבודה עם Kubernetes/Openshift תהיה הרבה יותר טובה ויעילה בהשוואה לשיטות העבודה הקלאסיות. שדרוגים לדוגמא מבוצעים בפקודה אחת מבלי להפסיק את כל החלקים השונים, ובמקרה הצורך, אותו דבר מתבצע בשנמוכים. את ה-HA מקבלים כברירת מחדל עם Kubernetes/Openshift, ובכל הקשור לאחסון – אותן מערכות יודעות "לדבר" עם כל אחסון מקומי או שקיים בענן ציבורי. מה עם אבטחה? כיום עם istio אפשר לעשות דברים רבים שבמערכות קלאסיות מצריכות תוכנות מסחריות (יקרות) מצד ג', ויש כמובן כלים נוספים, רובם בקוד פתוח זמינות לציבור.

אנסה לסכם את הפוסט כך: כיום, אם יש צורך בפיתוח אפליקציות גדולות ומורכבות, עדיף לעבוד במתודות ה-Microservices (ואגב, לחובבי ה-Mainframe – כן, אפשר לעשות זאת בקרוב גם על Mainframe של IBM עם Z/OS) שנותנות יתרונות רבים מאוד על פני המתודה המונוליטית. נכון, Kubernetes הוא לא בדיוק דבר קליל ללימוד אך מצד שני, המאמץ שווה, מה גם שאם אתם הולכים להשתמש בעננים ציבוריים, החיים הרבה יותר קלים עם שרותי הקונטיינרים הטבעיים שאותם ספקי ענן ציבורי מציעים.

להלן מצגת (קצת ישנה) על הנושא (ותודה ליבגני זיסליס על הלינק):