3.1 מונוליט לעומת מיקרוסרביסים הרצאה
מונוליט לעומת מיקרוסרביסים¶
אחת השאלות הנפוצות בארכיטקטורת מערכות היא: "האם כדאי לפצל את המערכת למיקרוסרביסים?"
אין תשובה אוניברסלית. נבין מה כל אחד מהם, ומתי להשתמש בכל אחד.
מונוליט - Monolith¶
מונוליט הוא מערכת שכל הקוד שלה נמצא ביחידת deploy אחת - קובץ אחד, תהליך אחד.
מבנה טיפוסי¶
taskflow/
main.py
routes/
tasks.py
users.py
projects.py
comments.py
services/
task_service.py
user_service.py
notification_service.py
repositories/
task_repo.py
user_repo.py
models/
task.py
user.py
הכל יחד, רץ בתהליך אחד, משתמש במסד נתונים אחד.
יתרונות המונוליט¶
פשטות בפיתוח: קוד אחד, סביבת פיתוח אחת, debug ישיר.
פשטות בdeployment: מריצים קובץ אחד. אין צורך לתאם בין מספר שירותים.
ביצועים: קריאות בין חלקי הקוד הן קריאות פנימיות בזיכרון - לא HTTP מעל רשת.
עקביות נתונים: מסד נתונים אחד - transactions מובנות מאליהן.
חסרונות המונוליט¶
קושי בהרחבה עצמאית: אם רק ה-notifications service עמוס, צריך להגדיל את כל המונוליט.
coupling: שינוי בחלק אחד עלול לשבור חלקים אחרים. ככל שהמונוליט גדל, קשה יותר לפתח במקביל.
deploy כבד: שינוי קטן מחייב deploy של כל המערכת.
מיקרוסרביסים - Microservices¶
מיקרוסרביסים הם ארכיטקטורה שבה המערכת מחולקת לשירותים קטנים ועצמאיים, כל אחד אחראי על תחום אחד.
TaskFlow כמיקרוסרביסים¶
user-service (port 8001) - הרשמה, התחברות, ניהול משתמשים
task-service (port 8002) - יצירה, עדכון, מחיקת משימות
project-service (port 8003) - ניהול פרויקטים
notify-service (port 8004) - שליחת מיילים, SMS, Push
search-service (port 8005) - חיפוש משימות ופרויקטים
כל שירות:
- יש לו מסד נתונים משלו
- יכול להיכתב בשפת תכנות אחרת
- מתקשר עם שירותים אחרים דרך HTTP או message queue
יתרונות המיקרוסרביסים¶
הרחבה עצמאית: notify-service עמוס? מוסיפים instances רק לו - לא לכל המערכת.
independence: כל צוות אחראי על שירות משלו. אפשר לעשות deploy לשירות אחד בלי לגעת בשאר.
גמישות טכנולוגית: task-service בפייתון, search-service ב-Go, notify-service ב-Node.js.
isolation: אם notify-service נופל, יצירת משימות עדיין עובדת.
חסרונות המיקרוסרביסים¶
מורכבות תפעולית: צריך לנהל 5+ שירותים, monitoring לכל אחד, load balancer, service discovery.
latency: קריאה בין שירותים היא HTTP דרך רשת - איטית בהרבה מקריאה פנימית.
distributed transactions: עדכון של task + שליחת notification - מה קורה אם ה-notification נכשל אחרי שהtask עודכן?
overhead פיתוח: צריך לנהל contracts בין שירותים, versioning של APIs, testing integration.
השוואה¶
| קריטריון | מונוליט | מיקרוסרביסים |
|---|---|---|
| מורכבות פיתוח | נמוכה | גבוהה |
| מורכבות תפעול | נמוכה | גבוהה |
| מדרגיות | מוגבלת | גבוהה |
| עצמאות צוותים | נמוכה | גבוהה |
| ביצועים | גבוהים | נמוכים יחסית |
| fault isolation | נמוכה | גבוהה |
מתי להשתמש בכל אחד?¶
מתי מונוליט?¶
- סטארט-אפ בשלב מוקדם - צריכים לנוע מהר
- צוות קטן (עד 10 מפתחים)
- הדומיינים עדיין לא ברורים - מוקדם לחלק
- כמות משתמשים שמונוליט יכול לטפל בה
"תמיד תתחילו עם מונוליט. אל תבנו מיקרוסרביסים מהיום הראשון." - Martin Fowler
מתי מיקרוסרביסים?¶
- צוותים גדולים שעובדים על חלקים שונים
- חלקים שונים של המערכת צריכים הרחבה שונה
- דרישות אמינות גבוהות - כשל בשירות אחד לא יפיל את הכל
- הדומיינים ברורים וניתן לחלק
Strangler Fig - דפוס המעבר¶
אם כבר יש לכם מונוליט ורוצים לעבור למיקרוסרביסים, השיטה המקובלת היא "Strangler Fig" - בדיוק כמו עץ תאנה חונק שגדל סביב עץ אחר:
- בונים שירות חדש עצמאי לצד המונוליט
- מנתבים חלק מהתעבורה לשירות החדש
- מסירים את החלק הזה מהמונוליט
- חוזרים על זה לכל שירות
שלב 1: מונוליט → כל התעבורה
שלב 2: מונוליט → רוב התעבורה, notify-service → התראות
שלב 3: מונוליט (ללא notifications) + notify-service
שלב 4: מונוליט (ללא notifications, ללא users) + notify-service + user-service
...
לאף אחד לא כותב מיקרוסרביסים "יש מאין" ביום אחד.
TaskFlow - מה נכון לנו?¶
בשלב הנוכחי של TaskFlow - מונוליט הוא הבחירה הנכונה. יש לנו:
- צוות קטן
- דרישות עסקיות שעדיין מתבהרות
- לא מאות אלפי משתמשים
אם TaskFlow תצמח ל-500,000 משתמשים עם 20 מפתחים - נשקול לחלץ notify-service ואולי search-service כמיקרוסרביסים ראשונים.