Table of Contents
הקדמה: רלוונטיות של MVC במערכות מבוזרות מודרניות
תבנית מודל-View-Controller (MVC) הייתה מושג אדריכלי בסיסי בהנדסת תוכנה במשך עשרות שנים.הפופולרית במקור על ידי Smalltalk-80 ולאחר מכן אומץ על ידי מסגרות אינטרנט כמו רובי על Rails, Spring MVC, ו- ASP.NET MVC, העיקרון הליבה של התבנית - פער של חששות - הוכח ללא זמן.
התשובה הקצרה היא כן, אבל לא באופן שבו היא הוחלה ביישומים מסורתיים של האינטרנט.שילוב עקרונות MVC למיקרו-שירותים דורש חשיבה מחדש על הגבולות של כל רכיב והבנה כיצד הם ממפה להפצת גבולות השירות. מאמר זה מספק ניתוח מעמיק של התפקיד של תבנית MVC במיקרו-שירותים אדריכלות, לחקור את האתגרים התאויים והיישום המעשיים.
בסוף, תהיה לך תמונה ברורה יותר של איך למנף את נקודות החוזק של MVC תוך כבוד לאוטונומיה ולדרישות הדרגתיות של מיקרו-שירותים.
תבנית MVC: A Quickמרעננים
לפני צלילה לתוך מערכות מבוזרות, זה שימושי כדי לשחזר את רכיבי MVC הקלאסי כפי שהם מבינים ביישומים אינטרנט מונוליטי.
- (FLT:0)ModelveFLT:1) - מכיל את מבני הנתונים ואת ההיגיון העסקי המגדירים את התחום של היישום.בהגדרה מסורתית, המודל הוא לעתים קרובות schema מסד נתונים אחד עם מיפוי אובייקטיבי (OR) כיתות.המודל מסמן את ראיית השינויים באמצעות דפוס צופה או באמצעות מדינה משותפת.
- (FLT:0)ViewofLT:1) - Handles theמצגת שכבת.It הופכת את הנתונים של המודל לממשק משתמש, בדרך כלל דף אינטרנט או מסך נייד.התצוגה מתעדת לעדכונים מודל וחידושים בהתאם.במסגרות החזית המודרניות, השקפות הן רכיבים תגובתיים שמנהלים את המדינה שלהם.
- (FLT:0)ControllerveFLT:1 - תהליכים הנכנסים קלט משתמש (בקשות HTTP, טופס הגשת, קליקים) זה מפריש את הקלט, אינטראקציה עם המודל לביצוע פעולות, ובחר את התצוגה המתאימה להציג את התגובה.
הכוח של MVC שוכן ב-FLT שלה:0 פיזור של חששות ⁇ 1 [שינויים בממשק המשתמש (המבט) לא משפיעים על לוגיקה עסקית (מודל), ולוגיקה ניתוק (בקר) ניתן לעדכן באופן עצמאי.מודולריות זו הפכה את MVC דפוס Go-to לבניית יישומים הניתנים לבחינה.
עם זאת, באדריכלות מיקרו-שירותים, הגבולות משתנים.כל מיקרו-שירות הבעלים של הנתונים וההיגיון שלו, והממשק המשתמש בנוי לעתים קרובות כיישומים קו החזיתיים נפרדים שמתקשרים עם שירותים מרובים.זה מעלה את השאלה: כיצד ליישם MVC כאשר אין יישום יחיד כדי לחלק?
Mapping MVC למיקרו-שירותים: The Distributed View
התגובה הטבעית היא לטפל בכל מיקרו-שירות כמו היישום MVC שלה.זוהי גישה תקפה עבור תרחישים מסוימים, במיוחד עבור שירותים לחשוף ממשק מבוסס משתמש ישירות (למרות שזה נדיר microservices) נפוץ יותר, microservices לחשוף APIs, ואת החזית היא צרכן נפרד. בהקשר זה, רכיבי MVC להיות מבוזרים על פני שכבות ארכיטקטוניות שונות.
מודלים כמידע של שירות-Owned
(ב) יישום MVC מונוליטי, המודל משותף על פני כל בסיס הקוד.במיקרו-שירותים, המודל הוא FLT:0decentralizedFLT:1; כל שירות הוא הבעלים הבלעדי של תחום הנתונים שלו.לדוגמה, AFLT:2 שירות הזמנה 3FLT ספציפי הוא מודל ההזמנה (כולל פריטים, מעמד, תשלום), בעוד ש-FLT5 הוא מודל של שירות כולל שירות כולל של שירות כולל:5D) עם מודל של שירות כולל של שירות כולל של שירות נתונים (D.
התוצאה היא שאין "מקור אמת" יחיד לכל הנתונים.שירותים מתקשרים באמצעות APIs או אירועים לסנכרון המדינה.זה דורש תכנון זהיר לשמירה על עקביות נתונים, לעתים קרובות באמצעות דפוסים כגון סיאגה או מיקור אירועים.עבור מבט מעמיק יותר על ניהול נתונים במיקרו-שירותים, ראה FLT:0, אפילו תבנית מתפתלת של 1FLT:1 על מיקרו-שירותי.
ראשי התיבות של API Gateways and Service Endpoints
ב- MVC הקלאסי, הבקר מקבל בקשה ומחליט מה לעשות.במיקרו-שירותים, התפקיד המקביל הוא שיחק על ידי FLT:0API GatewaysFLT:1 ואת בקרי נקודת הקצה של השירות עצמו.שער ה- API פועל כנקודת כניסה אחת לבקשות הלקוח, ניתח אותם לשירותים המתאימים, העלאה של תגובות, ולטפל בדאגות חוצה-PTS כמו תקן שירות מיקרו-C נכנס (או שירות).
הפרדה זו פירושה כי האחריות "בקר" מתחלקת בין השער (אשר מטפל בתזמורת ובקצב) לבין השירות (אשר מטפל בלוגיקה התחוםית) זהו הרחבה טבעית של MVC: שכבת הבקר נותרה הממשק בין קלט למשתמש לבין פעילות דומיין, אך היא מופץ כעת על פני התשתית.
החזית של החזית Micro Frontends
הנוף בסביבה מיקרו-שירותים הוא כמעט תמיד יישום בצד הלקוח.היש צורך עצמו בנוי באמצעות תבניות MVC (למשל, תגובה עם Redux או Angular עם שירותים), אבל זה צרכן חיצוני. לחלופין, את הנוף ניתן לפסל לתוך FLT:0 מיקרו חזיתות מקודמות 1 - בתוך דיבידנדים עצמאיים כי כל אחד מהם שייך לעקרון שירות ספציפי של צוותים משלו.
לדוגמה, חיפוש המוצר עשוי להיות קו החזית של מיקרו בבעלות צוות שירות קטלוג, בעוד שבדקו הוא בבעלות צוות שירות ההזמנה.כל פיסת ספו הופכת את UI שלה ומתקשרת עם ממשק API ה-Reend המקביל שלה.זהו הרחבה ישירה של MVC: כל מיקרו-end פועל כעין עבור מודל השירות שלה, וההוראה (או הקליפה) פועלת כמשתמש בקרטינג בין הזרמים.
עבור יותר על גבי קווי החזית של מיקרו, ראה את המאמר:0Micro FrontendsFOVAs 1LT על ידי קמר ג'קסון בבלוג של מרטין פוולר.
היתרונות של החלת עקרונות MVC למיקרו-שירותים
כאשר נעשה נכון, באמצעות חשיבה MVC בסביבה מבוזרת מניבה מספר יתרונות מעבר לארגון קוד פשוט.
המונחים: Modularity
לכל מיקרו-שירות יש הפרדה ברורה בין הרכיבים הפנימיים שלו.על ידי מתן שם של רכיבים אלה מודל, תצוגה (אם רלוונטי), ומפקח, הצוותים יכולים לשמור על עקביות על שירותים.מודולריות זו מקלה על החלפת יישום.לדוגמה, אתה יכול להחליף את מנגנון ההתמדה של מודל השירות ללא השפעה על ה- API שלו (בקר) או קדמית (view).
סקלאלה עצמאית
מכיוון שכל מיקרו-שירות הוא יחידת פריסה נפרדת, אתה יכול לדרג את החלק "בקר" (PI Gate) ואת "מודל" חלק (העתקים בשירות) באופן עצמאי.לדוגמה, במהלך מכירה פלאש, אתה יכול להגדיל את מודל שירות ההזמנה באופן אופקי כדי להתמודד עם עומס כתיבה מוגבר, בעוד מודל השירות הממציאי עשוי להיות צריך אסטרטגיה מדרג שונה.
צוות Autonomy
הפרדת החששות של MVC מתורגמת היטב לארגון הצוות.קבוצה אחת יכולה להחזיק את "מודל" של שירות התשלומים, צוות אחר יכול להחזיק את "ההשקפה" (המבחן UI micro Frontend), וצוות פלטפורמה יכול להחזיק את שער ה- API (הבקר הגלובלי) זה תואם לחוק קווויי: מערכות דומות למבנים התקשורת שלהם.
שיפור יכולת
רכיבים מסולקים הופכים את הבדיקות לקלות יותר.מודלים של השירות ניתן לבדוק ללא חששות HTTP.מפקחים (API נקודות קצה) ניתן לשלב נבדקים עם מודלים ללעג. תצוגות (רכיבים הקדמיים) ניתן לבדוק בבידוד באמצעות תגובות לעג API.זה אסטרטגיה בדיקה שכבתית ידועה מ-MVC מונוליטי וקשקשים באופן טבעי לתוך ארכיטקטורות מבוזרות.
אתגרים קריטיים באינטגרציה MVC-Microservices
בעוד היתרונות הם משמעותיים, האופי המופץ של microservices מציג מורכבות שאינם קיימים ביישום יחיד מעבד MVC. Ignoring אתגרים אלה יכול להוביל מערכות שבריריות כי קשה יותר לשמור על מאשר חלופה מונוליטית.
ניהול עסקאות
באפליקציית MVC מונוליטית, המודל לעתים קרובות משתמש מסד נתונים יחיד, מה שהופך עסקאות ACID פשוט.במיקרו-שירותים, לכל שירות יש מסד נתונים משלו.מבצע עסקי המשתרע על שירותים מרובים (למשל, הצבת הזמנה decrements מלאי וחיוב כרטיס אשראי) לא יכול להשתמש בעסקה מבוזרת אחת ללא זמינות הקרבה.
לעתים קרובות הצוותים מזלזלים במאמץ הנדרש ליישום הסאגות נכון, למדריך מעשי, ראו דפוס של 0Saga FigFLT:1 על מיקרו-שירותים.io.
עמידות לנתונים ולחוסר
ב MVC, התצוגה יכולה מיד לשקף שינויים במודל בגלל זיכרון משותף או גורם מסד נתונים.במיקרו-שירותים, אירועים propagate asynchronly.משתמש עשוי לראות נתונים מסולקים בנוף אם התגובות הקדמיות או אם הפחתת אירוע זה.זה בסופו של דבר מודל עקבי דורש עיצוב UX זהיר - מראה ספיננרים, עדכונים אופטימיים, או אינדיקטורים מעמד זמני.
יתר על כן, בקר ה- API חייב להתמודד עם כשלים חלקיים בחסד אם שירות מטהר אחד נכשל, השער עשוי להחזיר תגובה חלקית או דעה מוזנחת.זה הרבה יותר מורכב מבקר מונוליטי שהצלחה או נכשל באופן אטומי.
מידע על מידע ותקשורת Overhead
באפליקציית MVC מונוליטית, הבקר קורא ישירות שיטות מודל באותו תהליך.במיקרו-שירותים, שיחות אלה הופכות לקריאות רשת.זה מגביר את הגמישות ומציג כישלונות פוטנציאליים (timeouts, retries, breakers מעגל) שכבת הבקר חייבת לשלב תבניות חוסן.בנוסף, מנגנוני גילוי שירות (למשל, קונסולס, DNS Kubnetes) נדרשים לאתר מודלים מוכנים לשרת קבוצות רבות.
גרסה ואבולוציה
ההפיכה ההדוקה של MVC בין בקר, מודל ונוף במונוליטיקלית קלה לשינוי כי כל הקוד הוא יחידה אחת פורה. במיקרו-שירותים, כל שירות מתפתח באופן עצמאי.שינוי במודל של שירות (למשל, שדה חדש או הסרת נקודות קצה) יכול לשבור את בקר שלו (שער API) או את ראייתו (חזית מיקרו).
שיטות מעשיות עבור MVC-Aware Microservices
כדי לממש את היתרונות תוך הקטנת האתגרים, כמה דפוסים אדריכליים הופיעו כי לפגוע MVC עם microservices.
חזרה ל- Frontend (BFF)
דפוס זה מרחיב את מושג הבקר על ידי יצירת שערי API נפרדים עבור כל סוג של לקוח (web, Mobile, IoT) כל BFF פועל כבקר המותאמים לצרכים של התצוגה הספציפית.זה מצטבר נתונים ממודלים מרובים של שירות ושולח תגובה מרופפתנת.זה נמנע מהבעיה של שער API כללי שמחייב צוותים קדמית להתמודד עם שינויים מורכבים של נתונים.
תבנית BFF היא התאמה טבעית עבור MVC: BFF הוא הבקר, שירותי מטה הזרם הם המודלים, והלקוח UI הוא הנוף.כל צוות BFF הבעלים של הבקר והנוף שלהם, בעוד שירותי מודל נשארים משותפים.
אחריות על אחריות (CQRS)
CQRS מפריד בין קריאה וכתיבה פעולות. במונחים MVC, המודל מחולק למודל כתיבה (commands) ומודל קריאה (queries) מחליט האם בקשה היא פקודה או שאילתה ודרכים אותו לשירות המתאים. תצוגות לעתים קרובות לצרוך מודלים ישירות באמצעות ממשקי API אופטימיזציה או תחזיות קוד-אירועי.תבנית זו מועילה במיוחד במיקרו-שירותים משום שהיא מאפשרת קריאה וניתן לכתוב באופן עצמאי עבור שאילתות שירות סטנדרטיות.
תקשורת Event-Driven
במקום שיחות סינכרוניות ישירות, שירותים מתקשרים באמצעות אירועים. A בקר (API Gateway או BFF) יכול פולטים אירוע פיקוד, ושירותי מודל לצרוך אותו ולפלט אירועים תוצאה.השקפות יכולות להירשם לאירועים כדי לעדכן את UI בזמן אמת. זה תואם את התבנית המקורית של MVC - תצוגות מעקב שינויים במודל באמצעות אירועים, אבל עכשיו אירועים אלה מופצים באמצעות מתווכים זה משפר את השקיפות, אבל בסופו של דבר מציג אתגרים של דבר, אבל בפועל.
תכונת API לעומת הודעה
כאשר בקר צריך נתונים ממודלים מרובים, שתי אסטרטגיות קיימות: הרכב API (הבקר קורא לכל שירות ישירות) או הודעות פיקוד (הבקר שולח בקשה ל כוריאוגרפיה של שירותים) הרכב API הוא פשוט יותר אך מגביר את הגמישות; הודעות הפיקוד מורכבות יותר אך מרתיעות את הבקר מזרימת הנתונים.בחירה בין אלה היא akin לבחור בין בקר סינכרוני לבין מסונכרן אחד ב MVC.
שיטות טובות עבור צוותים אימוץ MVC+Microservices
בהתבסס על ניסיון בעולם האמיתי, שקול את ההנחיות הבאות:
- (FLT:0) להגדיר באופן אקספונציאלי גבולות שירות באמצעות עיצוב Domain-Driven Design.FLT:1 מודל השירות של כל שירות צריך להתאים להקשר כבול.
- (FLT:0) השתמש שער API או BFF כבקר הראשי.FLT:1 אל תתנו לאפליקציות של הלקוח להתקשר ישירות לשירותים מרובים - הם יהפכו להיות משותפים הדוקים לטופולוגיה האחורית.
- (FLT:0) סטובורד על פרוטוקולי תקשורת וחוזים נתונים.FLT ( 1:1 השתמש OpenAPI עבור REST או Protobuf עבור gRPC כדי להבטיח כי אינטראקציות מודל בקר מוגדרות היטב וגרסהed.
- (ב) ⁇ :0) ⁇ ⁇ מיום יום אחד (הראשונה ל- 1) דיסטריוט, חסימה, ומדיקות מסייעות לפענוח בעיות בשכבות MVC כאשר הדברים משתבשים.
- (FLT:0) למתן שימוש בסאגות לזרימות עבודה חיוניות בשירות הצלב.FreaLT:1 היכן שניתן, גבולות עיצוב כך שניתן יהיה לטפל בפקד אחד על ידי שירות אחד (שובה היא עלות מורכבות).
- (FLT:0) שמור על צריכת פשוטה: FLT:1 לא צריך לדעת על שירות פנימי. BFFs יכול לאסוף נתונים כדי להתאים את הצרכים של הנוף.
- (FLT:0) בבדיקות חוזה אוטומטיות.FIRLT:1 כלים כמו פאקט יכולים לאמת כי בקר (BFF) ומודל (שירות) מתפתחים ללא שבירת אחד את השני.
מסקנה: MVC כפילוסופיה מגוננת, לא תבנית ריידית
דפוס MVC אינו מיושן בעידן של מיקרו-שירותים. להיפך, העיקרון הליבה שלו - ההשוואה של חששות - הוא אפילו יותר חשוב כאשר רכיבים מחולקים ברשתות.עם זאת, החל מ- MVC למיקרו-שירותים דורש שינוי מהמחשבה על זה כמבנה מעמדי לחשוב עליו כפילוסופיה ארכיטקטונית שבה מודלים הם נתונים של שירות, בקרים הם שערים ושכבות תזמורת, השקפות ויישומים של לקוח או קדמית.
כאשר ייושמו בחשיבה, ארכיטקטורות מיקרו-שירותים בהשראת MVC נהנים ממודולריות, קיבולת עצמאית ואוטונומיה צוות.האתגרים - להפיץ עסקאות, עקביות ותקשורת מעל הראש - הם אמיתיים, אבל הם יכולים להיות מנוהלים עם דפוסים כמו BFF, CQRS, ועיצוב מונחה אירוע.המפתח הוא להימנע מעומס על הסביבה ללא מורכבות, להתאים את המציאות של תקשורת מבוזרת, במקום להתאים את עצמה, דפוס תקשורת מבוזר.
בסופו של דבר, המטרה נותרה זהה לפני חמישים שנה: בניית מערכות שניתן לשמר, לבחון ולקבוע מחדש את ה- MVC, כאשר הן מוחלות ברמה האדריכלית, מספקת את המסגרת המושגית להשגת מטרה זו במיקרו-שירותים.עבור קריאה נוספת על שילוב דפוסים, הספר FLT:0Building MicroservicesFal 1LT:1 על ידי סם ניומן הוא משאב מצוין, ו-FLT2 מציע קטלוג חשיבה משלים של מיקרו-FLT.