Micro-Services: מה עומד מאחורי הטרנד של עולם הקוד הפתוח?

הצצה לרעיונות החדשים שמביא איתו עולם ה-Micro-Services, ביתרונות שהוא מציע, ובחסרונות הבלתי נמנעים.

shutterstock open

הפוסט נכתב על ידי עדי ברון, ארכיטקט פיתוח בכיר בטיקל.

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

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

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

המונולית

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

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

• UI
• Account Service
• Inventory Service
• Shipping Service
• etc

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

בעולם הג׳אווה, לדוגמא, הכוונה היא לקובץ war אחד שרץ על Servlet Container כלשהו:

1

היתרונות הגדולים שפתרונות מהסוג הזה מציעים הם – קלות ופשטות: סביבת פיתוח סבירה תתמוך בחיבור לסביבת ריצה ותאפשר עדכון מתמשך של הקוד ללא צורך בהרצת תהליכי בניה ופריסה, ובכך תקצר ותפשט את מחזור הפיתוח. אוטומציה של מחזור החיים של המערכת היא משימה פשוטה יחסית ולכן למהנדסי הבדיקות קל לרוץ במקביל לפיתוח, כנ״ל עבור סביבת ה-Production. כשמתעורר הצורך בשיפור ההתמודדת של המערכת מול כמות גדלה של מידע ומשתמשים (Scale) מוסיפים עוד עותקים של המערכת ומציבים את כולם מאחורי Load Balancer (חומרה או תוכנה).

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

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

כמות גדולה של שורות קוד מקשה על הבנת המערכת, וכשלא מבינים מה קורה קשה יותר לתקן שגיאות ולפתח תכנים חדשים. פה ושם צצים להם שכפולי קוד שהסיבה להם היא ההיכרות המוגבלת עם הקוד או הפחד לשנות קוד משותף ולגרום בעיות במקום אחר לא ידוע. סביבת הפיתוח הפכה לכבדה ומסורבלת והעדכון האוטומטי של השרת הופך למעיק ולבסוף מגיע השלב בו צוות הפיתוח מרים ידים ומחליט לחזור לדרך הייסורים המוכרת של – כתיבת קוד >> בנייה של המערכת >> פריסה על השרת (שגם הוא הפך להיות בעיה שדורשת תשומת לב והתעסקות תכופה בענייני זיכרון, GC, connection pools, וכו׳) >> והתחברות מרחוק במוד debug. לא כיף בכלל. וזה עוד לפני שדיברנו על הכמות הגדולה של המפתחים שדרושה על מנת לתחזק את המפלץ – כולם כותבים לאותו המקום, דורכים אחד לשני על האצבעות, ״שוברים״ את ה- build, והופכים משימות של שעה וחצי לימים שלמים של התעסקות בשטויות.

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

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

Micro Services

הגישה בעולם המיקרו-שירותים דומה מאד לגישה מעולם ה- nix-utils*: עשה דבר אחד טוב (do one thing well). אם ניקח את הדוגמא איתה התחלנו ונתאים אותה לקונספט החדש כנראה שנקבל משהו כזה:

2

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

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

• ריבוי החלקים, דרכי הניטור וטיפול בתקלות.
• ניהול טרנזקציות (אחת האפשרויות היא הפרדה של בסיסי נתונים, כמו בתרשים האחרון).
• תכונות המבוזרות מעל כמה שירותים (cross service features), מימוש ופריסה.
• דרכי התקשורת בין השירותים השונים (sync/async http/amqp, xml/json/protobuf, וכו׳).

אם עד עכשיו נתתי יותר סיבות ל-״למה לא לממש Micro-Service Architecture״, אז הנה כמה ל- ״למה כן״:

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

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

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

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

• כאשר לכל שירות יש מחזור חיים נפרד, קל יותר לבצע תיקון שגיאות או להוסיף תכנים (במיוחד כשכמות הקוד היא קטנה) ולבצע עדכון של השירות בסביבת Production. כמובן שהפסקת שירות בסביבת הריצה תעורר בעיות בצד שירותים אחרים שמשתמשים באותו השירות שעובר עידכון, אבל גם לזה יש פיתרון – דפוס הנקרא Circuit Breaker שאותו אני מאד ממליץ ללמוד וכדוגמא לממימוש לקחת את Hystrix של Netflix.

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

הנושא האחרון אותו אני רוצה להזכיר בקצרה נוגע בתהליכי הפיתוח, הבדיקות, והאוטומציה. בעולם ה Micro-Services התהליכים הללו יותר מסובכים והמימוש שלהם דורש יכולות שבדר״כ לא קיימות בצוותי פיתוח. מאחר וסביבת הריצה של המערכת כוללת הרבה שירותים ומכונות, מיכון התהליך שמרים את כל העולם הזה לאוויר הוא לא משימת פיתוח שגרתית וחייבת להיות מעורבות של אנשי IT. נעשה שימוש במוצרים כמו Vagrant ו-OpenStack שמאפשרים לממש את הצורך הזה, מה שגורם למרחק בין עולם הפיתוח לעולם ה- Production להתקצר באופן משמעותי. אני רואה במעורבות של קבוצות האוטומציה וה- IT וקירבה שלהן לקבוצת הפיתוח דבר חיובי מאד, שמביא בסופו של עניין לסביבת ריצה יציבה יותר, ולא פחות חשוב מערכת יחסים בריאה בין החטיבות השונות.

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

קרדיט תמונה: open via Shutterstock.

הכתבה בחסות Tikal

"אנו בטיקל מזמינים אתכם להצטרף לקבוצת המיטאפ: Full Stack Developers Israel , ב
ה תוכלו להמשיך ולהעמיק את הידע בנושא זה ואחרים ע"י טובי המומחים בתחום. יתכן ותמצאו עניין באחד מאירועים קרובים אלו:
The Big Bang - Micro Services with RabbitMQ, Angular, Go, Sensu, Storm & Docker
Chef & Vagrant workshop

Avatar

Tikal

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

הגב

5 תגובות על "Micro-Services: מה עומד מאחורי הטרנד של עולם הקוד הפתוח?"

avatar
Photo and Image Files
 
 
 
Audio and Video Files
 
 
 
Other File Types
 
 
 

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

סידור לפי:   חדש | ישן | הכי מדורגים
עופר
Guest
כתבה מקסימה, תודה. בצירוף מקרים מדהים, היתה היום הרצאה ב-ALT.NET Melbourne בדיוק על זה, ואפילו עם אותה דוגמא של השירותים שבשימוש באתר מסחר: Agile Architecture Using Micro Services Tuesday, Jan 28, 2014, 6:00 PM Kiandra IT28/570 Bourke st Melbourne, AU 40 Members Went Sorry for the late notice guys but January is always a little difficult to get things together. But this week we have an architecture and distributed systems theme with some topics I thought might provide some interesting contrast to some discussions we’ve been having recently.Agile Architecture Using Micro Services – Jim PelletierJim will outli… Check out this… Read more »
משה
Guest

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

“מקובל לפתח ממשק משתמש (JavaScript, HTML) בנפרד מהשרת, תוך כדי דימוי השרת בעזרת כלים פשוטים ולבצע תהליך קצר של אינטגרציה כששני הצדדים מוכנים”

את זה דווקא לא הכרתי, אתה יכול להביא דוגמאות? כלים?

תודה רבה

עדי
Guest

כמו שמיקו הגיב, קיימות תשתיות כמו Yeoman שעוזרות בניהול פיתוח פרוייקטי ווב. אחד הדברים שנהוג לעשות בזמן הפיתוח הוא להתשמש בספריות Mock ש״מתלבשות״ על פונקציונאליות הגישה לשרת ומחזירות תשובה סינטטית במקומו. דוגמאות:
1) ב angularjs קיים שירות שנקרא httpBackend$.
http://docs.angularjs.org/api/ngMock.$httpBackend
2) עבור jQuery, אחת מהאפשרויות היא jquery-mockjax
https://github.com/appendto/jquery-mockjax

וכו׳

עמירם
Guest

יפה מאוד ומעניין. תודה!

מיקו
Guest

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

wpDiscuz

תגיות לכתבה: