דפוס התאנה החונק: דרך בטוחה להעברת יישומים מונוליטיים
בהנדסת תוכנה מודרנית, יישומים מונוליטיים מדור קודם הם אתגר נפוץ. עם הזמן, בסיס קוד מוצלח גדל כל כך גדול ומקושר זה לזה עד שביצוע שינויים פשוטים הופך למסוכן, פריסות נמשכות שעות, ושינוי קנה מידה של תכונות בודדות הוא כמעט בלתי אפשרי.
כאשר צוותים מחליטים לחדש את המערכות שלהם על ידי מעבר לשירותי מיקרו, הם מתמודדים עם שאלה בעלת סיכון גבוה: כיצד נשכתב את המערכת מבלי לשבור את העסק הנוכחי שלנו?
אפשרות אחת היא שכתוב “המפץ הגדול” - בניית המערכת החדשה מאפס מאחורי דלתות סגורות והחלפת הכל ביום אחד. עם זאת, זה מסוכן להפליא ולעיתים קרובות מוביל לכישלון.
למרבה המזל, יש חלופה בטוחה ואמינה יותר: דפוס התאנה החונקת. במדריך זה, נחקור מהי דפוס התאנה החונקת, מדוע היא פועלת וכיצד ליישם אותה שלב אחר שלב באמצעות דיאגרמות ברורות וקוד בעולם האמיתי.
האנלוגיה של העולם האמיתי: צמח התאנה החונקת
הדוגמה נקראת על שם תאנה החונקת, צמח שמקורו ביערות גשם טרופיים.
זרע תאנה חונק נובט בענפים העליונים של עץ “מארח” קיים. במקום לגדול מהאדמה, התאנה גדלה כלפי מטה:
- הוא שולח שורשים במורד הגזע של העץ המארח עד שהם מגיעים לקרקעית היער ועוגנים באדמה.
- עם הזמן צומחים שורשים נוספים, עוטפים את המארח ומתמזגים יחדיו.
- התאנה מצמיחת עלים שחוסמים את האור מלהגיע לעץ המארח.
- בסופו של דבר, העץ המארח מת ונרקב ומשאיר עץ תאנה חונק חלול עומד בחוזקה במקומו.
בארכיטקטורת תוכנה, מונוליט מורשת הוא העץ המארח, ושירותי המיקרו החדשים הם תאנה החונקת. אנו בונים את השירותים החדשים סביב קצוות המונוליט, ומעבירים בהדרגה את התעבורה הרחק מהמערכת הישנה עד שניתן יהיה לסגור את המונוליט לחלוטין.
מדוע שכתוב “המפץ הגדול” נכשל
לפני שנצלול לתוך המכניקה של דפוס התאנה החונקת, בואו נבין מדוע האלטרנטיבה - שכתוב מלא - מסוכנת כל כך:
- ללא ערך לחודשים (או שנים): מפתחים מבלים זמן רב בכתיבת קוד, אבל אף אחד מהם לא עולה לאוויר עד שהפרויקט כולו יושלם.
- Scope Creep: במהלך שכתוב של שנתיים, הצרכים העסקיים משתנים. המטרה זזה, והמערכת החדשה צריכה לתמוך בתכונות שלא היו קיימות כשהשכתוב החל.
- חסרה התנהגות מרומזת: מונוליטים מכילים שנים של תיקוני באגים לא מתועדים וטיפולים במקרי קצה. שכתוב של לוח נקי לעתים קרובות שוכח את הפרטים האלה.
- סיכון פריסה גבוה: כיבוי מערכת מדור קודם והפעלת מערכת חדשה בבת אחת יוצרת רדיוס פיצוץ עצום אם משהו משתבש.
איך פועל דפוס התאנה החונק
הרעיון המרכזי של דפוס תאנים חנוק הוא הגירה מצטברת. במקום להעביר את כל המערכת, אתה מעביר תכונה קטנה או “פרוסה” אחת בכל פעם.
תהליך ההגירה מתבצע בחמישה שלבים מרכזיים:
1. זהה הקשר מוגבל
התבונן במונוליט שלך וזיהה יכולת עסקית יחידה, עצמאית שקל לחלץ אותה. מועמדים טובים כוללים:
- תכונות המשתנות בתדירות גבוהה (כך שהצוות מרוויח מהר מפריסות עצמאיות).
- תכונות פשוטות בסיכון נמוך (כמו שאלות נפוצות סטטיות או סעיף העדפות משתמש) לבדיקת צינור ההגירה.
- תכונות עם גבולות מסד נתונים נקיים ומוגדרים היטב.
2. יישם את המיקרו-שירות החדש
בנה את היכולת שזוהתה כמיקרו-שירות חדש לגמרי ומודרני. לשירות זה יש מסד נתונים משלו, צינור פריסה משלו, והוא בנוי באמצעות ערימות טכנולוגיה מודרניות. באופן מכריע, התכונה הישנה במונולית נשארת פעילה וללא שינוי לעת עתה.
3. הצג את שכבת היירוט
כדי להפוך את ההעברה לשקופה למשתמשים שלך, אתה מציג שכבת יירוט (כגון שער API או פרוקסי הפוך) מול האפליקציה. כל תעבורת הלקוח עוברת כעת אל השער הזה תחילה.
בתחילה, השער מנתב 100% מכל הבקשות אל המונוליט מדור קודם.
4. מעבר תנועה בהדרגה
לאחר שהמיקרו-שירות החדש נבדק במלואו ומוכן, אתה מעדכן את כללי הניתוב בשכבת היירוט. במקום לנתב בקשות עבור התכונה שהועברה (למשל, /api/users) אל המונוליט, השער מפנה אותן לשירות המיקרו החדש.
כל שאר הבקשות ממשיכות לעבור אל המונוליט. אם השירות החדש נכשל או מציג באגים, אתה יכול לעדכן במהירות את השער כדי לנתב את התנועה חזרה אל המונוליט, תוך הבטחת הפרעה מינימלית.
5. ביטול וחזור
לאחר שהמיקרו-שירות החדש פועל ביציבות למשך תקופה מסוימת, אתה יכול למחוק בבטחה את הקוד המתאים בתוך המונוליט הישן.
לאחר מכן אתה בוחר בתכונה הבאה וחוזר על התהליך. עם הזמן, המונוליט מתכווץ עד שלא נותרה לו תעבורה, ותוכל לבטל לחלוטין את השרת הישן.
שכבת היירוט: דוגמה לניתוב אקספרס
הלב של דפוס התאנה החונקת הוא שכבת היירוט. זה מאפשר לך להפנות בקשות מחדש מבלי לשנות את יישומי הלקוח (אפליקציות אינטרנט, אפליקציות לנייד).
הנה דוגמה מעשית של Node.js באמצעות פרוקסי שער מבוסס Express. הוא מנתב בקשות באופן דינמי: בקשות נכנסות עוברות לשירותים החדשים אם הן תואמות לנתיבים שהועברו; אחרת, הם נופלים בחזרה אל המונוליט המורשת.
const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');
const app = express();
const PORT = 8080;
// Configuration: Target server URLs
const LEGACY_MONOLITH_URL = 'http://legacy-monolith-server:3000';
const NEW_USER_SERVICE_URL = 'http://new-user-service:3001';
const NEW_PAYMENT_SERVICE_URL = 'http://new-payment-service:3002';
// Simple logging middleware to track traffic distribution
app.use((req, res, next) => {
console.log(`[ROUTE LOG] Incoming request: ${req.method} ${req.url}`);
next();
});
// 1. MIGRATED: User registration & profile requests route to the new microservice
app.use('/api/users', createProxyMiddleware({
target: NEW_USER_SERVICE_URL,
changeOrigin: true,
pathRewrite: {
'^/api/users': '/v1/users', // Translate path format if necessary
}
}));
// 2. MIGRATED: Payment transactions route to the new payment microservice
app.use('/api/payments', createProxyMiddleware({
target: NEW_PAYMENT_SERVICE_URL,
changeOrigin: true
}));
// 3. FALLBACK: All other legacy routes automatically default to the Monolith
app.use('/', createProxyMiddleware({
target: LEGACY_MONOLITH_URL,
changeOrigin: true
}));
app.listen(PORT, () => {
console.log(`Interception Gateway routing traffic successfully on port ${PORT}`);
});
טיפול במסד הנתונים: החלק הקשה ביותר
בעוד שנית תעבורת API הוא קל יחסית, ניהול נתונים הוא ההיבט המאתגר ביותר של הגירה מונוליטית. למונוליט יש בדרך כלל מסד נתונים יחיד ומסיבי שבו טבלאות מחוברות מאוד.
כאשר אתה מחלץ שירות, עליך לחלץ גם את הנתונים שלו. ישנן שתי גישות נפוצות לטיפול בזה:
- כתיבה כפולה: שכבת היירוט או האפליקציה כותבת נתונים הן למסד הנתונים הישן והן למסד הנתונים החדש של השירותים בו זמנית במהלך שלב המעבר. זה שומר על שני מסדי הנתונים מסונכרנים.
- Change Data Capture (CDC): כלי כמו Debezium מנטר את יומן העסקאות של מסד הנתונים הישן ומזרים שינויים אוטומטית למסד הנתונים החדש של המיקרו-שירותים כמעט בזמן אמת.
ברגע שאתה בטוח שבסיסי הנתונים מסונכרנים במלואם ומסד הנתונים החדש תקין, אתה מעביר את תעבורת הקריאה לשירות החדש ומכבה את הטבלאות הישנות.
השוואה: שכתוב המפץ הגדול לעומת Strangler Fig
| תכונה / מדד | המפץ הגדול שכתוב | דפוס תאנה חונק |
|---|---|---|
| רמת סיכון | גבוה במיוחד | נמוך ומנוהל |
| לולאת משוב | מאוד איטי (רק בסוף) | מהיר (בדיקות ייצור רציפות) |
| אסטרטגיית החזרה חוזרת | קשה (דורש שחזור גיבויים) | קל (שנה כללי מסלול בשער) |
| השפעה עסקית | משבש | אפס זמן השבתה |
| מורכבות המערכת | גבוה (בשלב הבנייה) | גבוה (בשלב ההגירה) |
| זמן פריסה | הוצאת סינגל מאסיבית | עדכונים קטנים ותכופים |
מסקנה
The Strangler Fig Pattern הוא תקן התעשייה להגירת מונוליטים לשירותי מיקרו. על ידי החלפת קוד מדור קודם בהדרגה ולא בבת אחת, אתה מבטל את הסיכון לכשל “המפץ הגדול”.
זה שומר על פריסות קטנות, מספק משוב מיידי מתעבורת ייצור אמיתית, ומאפשר לצוות שלך להמשיך לספק ערך עסקי לאורך כל מחזור חיי ההגירה.
בעוד שניהול העברת מסדי נתונים והפעלת שתי מערכות מקבילות מוסיף מורכבות תפעולית, הבטיחות, הניבוי והיציבות שהוא מציע הופכים אותו לבחירה המועדפת עבור העברות ענן מודרניות.