לדלג לתוכן

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. מנתבים חלק מהתעבורה לשירות החדש
  3. מסירים את החלק הזה מהמונוליט
  4. חוזרים על זה לכל שירות
שלב 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 כמיקרוסרביסים ראשונים.