זהו המדריך השני בתוכנית לימודים שמלמדת איך ליצור מודולריזציה לאפליקציה מונוליטית ולהכניס אותה לקונטיינר.
תוכנית הלימודים כוללת את המדריכים הבאים:
- סקירה כללית
- הסבר על המונולית
- פירוק המונוליט למודולים (המדריך הזה)
- הכנת האפליקציה המודולרית להעברה לקונטיינר
- העברת האפליקציה המודולרית לקונטיינר
- פריסת האפליקציה באשכול GKE
במדריך הקודם, הסבר על אפליקציה מונוליטית, למדתם על אפליקציה מונוליטית בשם Cymbal Books. הפעלתם את המונוליט במחשב המקומי שלכם והבנתם שחלקים שונים במונוליט מתקשרים זה עם זה דרך נקודות הקצה שלהם.
במדריך הזה נראה איך מחלקים את המונוליט למודולים כדי להכין אותו להעברה לקונטיינר. אתם לא צריכים לבצע את השלבים של המודולריזציה בעצמכם, כי הקוד כבר עודכן בשבילכם. המשימה שלכם היא לפעול לפי ההוראות במדריך ולעיין בגרסה המודולרית של האפליקציה במאגר כדי לראות את ההבדלים בינה לבין המונוליט המקורי.
עלויות
אפשר להשלים את המדריך הזה בלי לשלם על כלום. עם זאת, אם תבצעו את השלבים שמפורטים במדריך האחרון בסדרה הזו, יחולו חיובים על חשבוןGoogle Cloud . העלויות מתחילות כשמפעילים את GKE ופורסים את אפליקציית Cymbal Books באשכול GKE. העלויות האלה כוללות חיובים לכל אשכול ב-GKE, כפי שמפורט בדף התמחור, וחיובים על הפעלת מכונות וירטואליות ב-Compute Engine.
כדי להימנע מחיובים מיותרים, הקפידו להשבית את GKE או למחוק את הפרויקט אחרי שתסיימו את המדריך הזה.
לפני שמתחילים
לפני שמתחילים את המדריך הזה, חשוב לוודא שסיימתם את המדריך הראשון, הסבר על המונולית. במדריך הזה מריצים את הגרסה המודולרית של Cymbal Books במחשב המקומי. כדי לעשות את זה, צריך להגדיר את הסביבה. אם כבר השלמתם את המדריך הראשון, שיכפלתם מאגר GitHub. כל שלוש הגרסאות של אפליקציית Cymbal Books נמצאות במאגר הזה, בתיקיות הבאות:
monolith/modular/containerized/
לפני שממשיכים, צריך לוודא שהתיקיות האלה נמצאות במחשב. בנוסף, מוודאים שהסביבה הווירטואלית book-review-env פעילה. אם אתם צריכים תזכורת לגבי אופן ההפעלה, תוכלו לעיין במאמר יצירה והפעלה של סביבה וירטואלית מהמדריך הראשון. הפעלת הסביבה מבטיחה שלגרסה המודולרית של האפליקציה יש את כל מה שהיא צריכה כדי לפעול.
מהי מודולריות?
במדריך הזה תלמדו איך להפוך את האפליקציה המונוליטית למודולרית כדי להכין אותה להעברה לקונטיינר. מודולריזציה היא תהליך שבו הופכים מונוליט לאפליקציה מודולרית. כמו שלמדתם במדריך הקודם, המאפיין המבדיל של מונוליט הוא שהרכיבים שלו לא יכולים לפעול או להתרחב באופן עצמאי. אפליקציה מודולרית שונה: הפונקציונליות שלה מחולקת למודולים שיכולים לפעול ולהתרחב באופן עצמאי.
למרות שלרוב מבצעים מודולריזציה וקונטיינריזציה יחד, בסדרת המדריכים הזו הם מוצגים כשלבים נפרדים כדי לעזור לכם להבין כל מושג בבירור. במדריך הזה מוסבר איך להפוך מונוליט למודולרי, ובמדריך מאוחר יותר מוסבר איך להוסיף את האפליקציה המודולרית למאגר.
מודולריזציה מצטברת
בסביבות ייצור, בדרך כלל מחלקים לרכיבים מודולריים רכיב אחד בכל פעם. מבצעים מודולריזציה של הרכיב, משלבים את המודול עם המונוליט ומוודאים שהכול פועל לפני שעוברים לרכיב הבא. המצב ההיברידי הזה, שבו חלק מהרכיבים מודולריים וחלקם נשארים חלק מהמונולית, נקרא מיקרולית. עם זאת, במדריך הזה, כל הרכיבים של האפליקציה עוברים מודולריזציה בו-זמנית כדי לספק דוגמה מלאה לאופן המודולריזציה של אפליקציה.
איך מחלקים את המונוליט למודולים
בקטע הזה תלמדו איך המונוליט של Cymbal Books פוצל למודולים נפרדים. השלבים מפורטים כדי לעזור לכם להבין את תהליך המודולריזציה, כך שתוכלו ליישם אותו באפליקציות שלכם. עם זאת, אין צורך לבצע את השלבים האלה במדריך הזה כי המאגר המשוכפל כבר כולל את הגרסה המודולרית של האפליקציה:
- זיהוי הפונקציות הייחודיות של האפליקציה
- יצירת המודולים
- הפעלת התקשורת בין המודולים
- הענקת גישה לכל מודול רק לנתונים שהוא צריך
זיהוי הפונקציות השונות של האפליקציה
השלב הראשון בפיצול המונוליט של Cymbal Books למודולים הוא זיהוי הפונקציות העיקריות שלו. באפליקציית הדוגמה Cymbal Books, למונולית יש את ארבע הפונקציות הנפרדות הבאות:
- הצגת דף הבית
- הצגת פרטי הספר
- הצגת ביקורות על ספרים
- הצגת תמונות של כריכות ספרים
יצירת המודולים
כפי שראיתם במדריך הקודם, המונוליט הוא אפליקציית Flask יחידה שמטמיעה את ארבע הפונקציות שזוהו בקטע הקודם כמטפלות בנתיבים. כדי להפוך את האפליקציה למודולרית, לוקחים כל handler של נתיב ומכניסים אותו לאפליקציית Flask משלו. במקום אפליקציית Flask אחת עם ארבעה handlers של נתיבים, יש ארבע אפליקציות Flask, שלכל אחת מהן יש handler אחד של נתיב בתוכה.
בתרשים הבא מוצג תהליך השינוי מאפליקציית Flask אחת לארבע אפליקציות Flask נפרדות:

באפליקציה המודולרית, כל אפליקציית Flask פועלת באופן עצמאי ומאזינה ליציאה אחרת (8080, 8081, 8082, 8083), כפי שמוצג בתרשים. ההגדרה הזו נדרשת כי בהמשך המדריך הזה תבדקו את האפליקציה המודולרית, ותריצו את כל המודולים באותו המחשב. לכל אפליקציה צריך להיות מספר יציאה שונה כדי למנוע התנגשויות.
למודול של דף הבית יש שתי משימות: הוא מציג את דף הבית ומתקשר עם המודולים האחרים כדי לאסוף נתונים שצריך להציג בדף אינטרנט. כל אחד מהמודולים האחרים מתמקד בפונקציה אחת: הצגת ביקורות, פרטים או תמונות. המודולים האלה לא מתקשרים ביניהם – הם מגיבים רק לבקשות מהמודול של דף הבית.
למרות שבמודול של דף הבית יש תפקיד נוסף של תיאום, האפליקציה עדיין מודולרית באמת כי אפשר לעדכן כל מודול בלי להשפיע על המודולים האחרים. אפליקציית Flask גדולה אחת חולקה לארבעה חלקים, וכל אחד מהם מטפל בחלק ספציפי בפונקציונליות של האפליקציה.
הפעלת תקשורת בין המודולים
אחרי שיוצרים את המודולים, השלב הבא הוא לוודא שהם יכולים לתקשר ביניהם. באפליקציית Cymbal Books, לוגיקת התקשורת הזו כבר הוטמעה בשבילכם. בתיקייה modular/ של הקוד שהורדתם, אפשר לראות שכל אחת מהתכונות העיקריות של האפליקציה – הצגת דף הבית, פרטי הספר, הביקורות והתמונות – מיושמת כאפליקציית Flask נפרדת. כל אחת מהאפליקציות האלה מגדירה נקודת קצה משלה של HTTP, והמודולים מתקשרים ביניהם באמצעות שליחת בקשות HTTP לנקודות הקצה האלה.
הפיכת המונוליט של Cymbal Books למודולרי הייתה פשוטה. למונולית יש רכיבים מוגדרים היטב שמיושמים כמטפלי נתיבים, ולכל מטפל נתיבים יש נקודת קצה מוגדרת היטב. כשמציבים את הפונקציות האלה לטיפול בבקשות במסגרת אפליקציות Flask נפרדות, הן שומרות על היכולת שלהן לתקשר דרך נקודות הקצה שלהן. הפעולה הפשוטה של העברת מטפלי המסלולים לאפליקציות Flask נפרדות יוצרת את המודולים ומאפשרת למודולים לתקשר זה עם זה.
גישה נפוצה לתקשורת בין מודולים היא הטמעה של ממשקי REST API, שמאפשרים למודולים לשלוח זה לזה בקשות HTTP. כך זה עובד ב-Cymbal Books: כל מודול מגדיר נקודות קצה של REST באמצעות הכלים המובנים של Flask. גישה פופולרית נוספת היא gRPC, שמאפשרת למודולים לקרוא ישירות לפונקציות של מודולים אחרים.
למה התקשורת ב-Cymbal Books פשוטה
כל מודול באפליקציה המודולרית הוא אפליקציית Flask נפרדת שפועלת בתוך שרת אינטרנט. לדוגמה, מודול דף הבית מוצג בדף הבית, ומודול פרטי הספר מוצג בדף פרטי הספר. התקשורת בין המודולים פשוטה כי שרתי אינטרנט מתוכננים לטפל בבקשות ובתגובות של HTTP. כל מודול חושף נקודות קצה שמודולים אחרים יכולים להשתמש בהן כדי לבקש נתונים.
לתת לכל מודול גישה רק לנתונים שהוא צריך
כדי להפוך את המונוליט למודולרי בצורה נכונה, צריך לוודא שלכל מודול יש גישה רק לנתונים שהוא צריך. העיקרון הזה, שנקרא בידוד נתונים, הוא מרכיב חיוני ביצירת ארכיטקטורה מודולרית באמת.
טעות נפוצה שאנשים עושים במהלך מודולריזציה היא לאפשר למודולים מרובים לגשת לאותם נתונים, כמו מסד נתונים יחיד. סוג ההטמעה הזה יוצר בעיות כמו:
- צימוד חזק: אם המבנה של הנתונים המשותפים משתנה – למשל, אם משנים את השם של טבלת מסד נתונים או מוסיפים עמודה – צריך לעדכן כל מודול שמסתמך על הנתונים האלה. כדי למנוע את הבעיה הזו, צריך להשתמש במודולריזציה נכונה.
- בעיות בסובלנות לתקלות: כשכמה מודולים משתמשים באותו מקור נתונים, כשלים בזמן ריצה במודול אחד – כמו שאילתות לא תקינות או תנועה עמוסה מדי – עלולים לשבש מודולים אחרים. כשל בחלק אחד של המערכת יכול להוביל לכשלים בחלקים אחרים של המערכת.
- צווארי בקבוק בביצועים: מקור נתונים יחיד ומשותף יכול להפוך לצוואר בקבוק, כלומר הוא עלול להאט את כל האפליקציה כשכמה מודולים מנסים ליצור איתו אינטראקציה.
כדי להימנע מהבעיות האלה, לכל מודול צריך להיות מקור נתונים משלו.
אם חברת Cymbal Books הייתה משתמשת במסד נתונים כדי לאחסן את הנתונים שלה, היה צורך לשכפל או לחלק את מסד הנתונים כדי לאכוף בידוד נתונים ולוודא שכל מודול ניגש רק לנתונים שהוא צריך. שכפול כולל שמירה של עותקים נפרדים של מסד הנתונים לכל מודול, בעוד שחלוקה למחיצות מגבילה את הגישה לטבלאות או לשורות ספציפיות. שתי הגישות מונעות ממודולים להפריע לנתונים של מודולים אחרים.
בתרשים הבא מוצגת השוואה בין הארכיטקטורה המונוליטית של אפליקציית הספרים לבין הארכיטקטורה המודולרית של אפליקציית הספרים:

ההטמעה של המונולית לא עומדת בדרישות של עיקרון בידוד הנתונים, כי הפונקציות של המונולית ניגשות לספרייה אחת של data/.
לעומת זאת, באפליקציה מודולרית מושג בידוד נתונים במידה מסוימת על ידי פיצול הנתונים לספריות נפרדות, ומוודאים שכל מודול יקיים אינטראקציה רק עם הנתונים שיועדו לו:
- מודול פרטי הספר מקבל נתונים רק מהספרייה
details_data/. - המודול 'ביקורות על הספר' מקבל נתונים רק מהספרייה
reviews_data/. - מודול התמונות מקבל נתונים רק מהספרייה
images/.
במדריך נוסף בהמשך, נראה איך אפשר לשפר עוד יותר את הבידוד של הנתונים באמצעות יצירת קונטיינר לאפליקציה.
מה שראיתם הרגע
בתעשיית פיתוח התוכנה, נתקלים לעיתים קרובות במונחים מיקרו-שירותים ומערכות מבוזרות. בקטע הזה נסביר איך המונחים האלה קשורים להטמעה המודולרית של Cymbal Books.
מיקרו-שירותים (microservices)
מיקרו-שירותים הם מודולים אוטונומיים שמבצעים משימות ספציפיות. המודולים האלה מתקשרים עם מודולים אחרים באמצעות ממשקים כמו נקודות קצה.
כל מודול בגרסה המודולרית של Cymbal Books מתאים להגדרה הזו, ולכן אפשר להתייחס אליו כאל מיקרו-שירות. כשמכניסים את האפליקציה המודולרית לקונטיינר במדריך מאוחר יותר, הקוד שרץ בתוך הקונטיינר יכול להיקרא גם מיקרו-שירות, כי זה אותו קוד שרץ בתוך מודול.
מערכות מבוזרות
מערכת מבוזרת מורכבת ממודולים עצמאיים שמתקשרים דרך רשת כדי להשיג מטרה משותפת. המודולים האלה יכולים לפעול במכונות שונות, אבל הם פועלים יחד כמערכת אחת.
אפליקציית Cymbal Books המודולרית מתאימה גם היא להגדרה הזו: המודולים שלה פועלים באופן עצמאי ומבצעים חילופי נתונים באמצעות HTTP, אבל ביחד הם פועלים כמערכת אחת. בקטע הבא, מריצים את כל המודולים במכונה אחת כדי לפשט את התהליך, אבל זה לא חובה. כל מודול יכול לפעול בקלות בשרת אחר, ולכן אפשר לסווג את הגרסה המודולרית של אפליקציית Cymbal Books כמערכת מבוזרת.
בדיקת ההטמעה המודולרית
עכשיו, אחרי שראיתם איך המונוליט של Cymbal Books הופך לאפליקציה מודולרית שהמודולים שלה הם אפליקציות Flask, אתם יכולים לבדוק את האפליקציה ולראות שכל מודול פועל באופן עצמאי.
במדריך הזה, מריצים את המודולים באותה מכונה. עם זאת, אפשר גם להריץ כל מודול בשרת נפרד: כל מודול הוא אוטונומי, ולכן הוא יכול לתקשר עם המודולים האחרים דרך נקודות הקצה שלהם.
מגדירים את הסביבה
כדי להתכונן לבדיקה:
במסוף, נכנסים לספרייה
modularבמאגר המשוכפל:cd modularמוודאים שהסביבה הווירטואלית
book-review-envפעילה. אם אתם צריכים תזכורת לגבי שלבי ההפעלה, תוכלו לעיין במאמר בנושא יצירה והפעלה של סביבה וירטואלית.
הפעלת אפליקציית Flask
התיקייה /modular מכילה סקריפט bash שמתחיל את כל אפליקציות Flask בו-זמנית. כל מודול באפליקציה מאזין ליציאה ייחודית, כמו 8080 או 8081:
- אפליקציית Flask בדף הבית (home.py): יציאה 8080
- Book details Flask app (book_details.py): port 8081
- Book reviews Flask app (book_reviews.py): port 8082
- Images Flask app (images.py): port 8083
כל מודול צריך להאזין למספר יציאה ייחודי, כי כל המודולים פועלים באותה מכונה. אם כל מודול היה בשרת אחר, כל אחד מהם היה יכול להאזין לאותו מספר יציאה בלי ליצור התנגשויות בין יציאות.
מריצים את סקריפט ה-bash באמצעות הפקודה הבאה:
bash ./start_services.sh
הסקריפט יוצר קובץ יומן נפרד לכל אפליקציית Flask (לדוגמה, home.py.log, book_details.py.log) כדי לעזור לכם לזהות בעיות בהפעלה.
כשהסקריפט מסתיים בהצלחה, מוצגת ההודעה הבאה:
All services have been started. Access the app at http://localhost:8080/
בדיקה של כל אפליקציית Flask
כדי לבדוק את המודולים, עוברים לכתובות ה-URL הבאות בדפדפן:
- דף הבית:
http://localhost:8080/מציג את דף הבית של אפליקציית הספרים המודולרית של Cymbal. בדף הזה מתקבלים פרטי הספר, ביקורות ותמונות על ידי שליחת בקשות למודולים האחרים. - Book details:
http://localhost:8081/book/1מחזירה את פרטי הספר עם המזהה 1. התגובה הזו היא נתוני JSON שהאפליקציה מעצבת ומציגה באופן קריא יותר. - ביקורות על ספרים:
http://localhost:8082/book/1/reviewsמאחזר ומחזיר את הביקורות על הספר עם המזהה 1. הביקורות הן בפורמט JSON. מודול דף הבית מבקש את הנתונים האלה ומשלב אותם בדף פרטי הספר. - Images:
http://localhost:8083/images/fungi_frontier.jpgמציג את תמונת השער של הספר Fungi Frontier. אם כתובת ה-URL נכונה, התמונה אמורה להיטען ישירות בדפדפן.
עצירת אפליקציות Flask
כשמסיימים את הבדיקה, מפסיקים את כל אפליקציות Flask באמצעות הפקודה הבאה:
kill $(cat home.py.pid book_details.py.pid book_reviews.py.pid images.py.pid)
סיכום
במדריך הזה למדתם איך להפוך את המונוליט של Cymbal Books למודולרי. התהליך כולל את השלבים הבאים:
- זיהוי הרכיבים השונים של האפליקציה
- יצירת המודולים
- לוודא שלכל מודול יש גישה רק לנתונים שהוא צריך
לאחר מכן בדקתם את ההטמעה המודולרית במחשב המקומי.
המאמרים הבאים
במדריך הבא, הכנת האפליקציה המודולרית להעברה לקונטיינר, מוסבר איך להכין את האפליקציה המודולרית להעברה לקונטיינר על ידי עדכון נקודות הקצה לשימוש בשמות של שירותי Kubernetes במקום localhost.