למה Azure Container Apps מאבד בקשות בשיא
Azure Container Apps מבצע סקיילינג של קונטיינרים לפי אירועים ומטריקות, אבל בשיא חד של תעבורה האפליקציה בכל זאת מתחילה להחזיר 5xx. הבעיה אינה במחסור במשאבים, אלא בהשהיה בלולאת הבקרה: ההחלטה להוסיף רפליקות מתקבלת לאט יותר מקצב גידול העומס.
חוק האוטוסקיילינג נשען על מטריקה ממוצעת בחלון תצפית — המונה צריך לצבור סטטיסטיקה לפני שהוא פועל. בזמן שהחלון מתמלא, מספר הבקשות במקביל לכל רפליקה כבר הוכפל, התור הנכנס גדל, ולמופעים חדשים עדיין לא נוצרו. סקיילינג הקונטיינרים מתקדם במדרגות, והתעבורה מגיעה בחזית.
בהמשך נכנסת התנעה קרה: הרפליקה צריכה לקבל את האימג', להעלות את הסביבה, להתחמם ולעבור בדיקת מוכנות. בשניות הראשונות היא או לא מקבלת תעבורה, או מקבלת אותה לא מחוממת — זמן התגובה בקטע הזה גבוה יותר מאשר אצל מופעים שכבר עובדים. אם בדיקות המוכנות מוגדרות פורמלית, הזרימה עוברת לתהליך שעדיין לא מחזיק חיבורים.
כך כשלים בשיא מורכבים משני גלים: תחילה הזרימה הנכנסת עולה על הקיבולת הנוכחית לפני שהאוטוסקיילינג פועל, ואחר כך חלק מהבקשות נופל על רפליקות לא מוכנות. במטריקות זה 503 בכניסה, עלייה באחוזון ה-95 וה-99 של זמן התגובה וניתוקי חיבורים אצל חלק מהלקוחות.
נפרק כיצד זה נסגר: חוקי אוטוסקיילינג מקדימים לעומס שיא, חימום והוצאה הדרגתית של תעבורה, כדי שהסקיילינג יספיק לפני שהתור הופך לכשלים.
מה נותן אוטוסקיילינג ופרסום קנארי
פרסום קנארי מחזיק שתי רביזיות בו-זמנית: אל החדשה עוברים 5-10% מהתעבורה, והשאר מטופל על ידי הקודמת. שיעור השגיאות וזמן התגובה של הרביזיה החדשה מושווים לבסיס בזמן אמת — בחריגה מהסף התעבורה חוזרת לרביזיה המאומתת תוך שניות. אין השבתה של השירות: המשתמש לא רואה לא הפעלה מחדש ולא ניתוקי חיבורים.
סקיילינג לפי אירועים משנה את פרופיל התגובה לעומס. רפליקות מתווספות לא לפי עומס המעבד, אלא לפי אורך התור ומספר ההודעות שלא נסגרו, ולכן פרץ לילי מטופל עשרות שניות לפני שסף לפי מטריקות חומרה היה פועל.
ב-Azure Container Apps חוקי הסקיילינג וחלוקת התעבורה בין רביזיות מתוארים דקלרטיבית, כך שההתנהגות תחת עומס משוחזרת בכל סביבת בדיקה, ולא מוגדרת מחדש.
מכאן — סוגי אירועים שמפסיקים להגיע למשתמש:
- הידרדרות אחרי שחרור: חזרה לאחור תוך שניות, ללא התערבות ידנית של התורן;
- כשל של אזור אחד: רפליקות עולות באזורים שנותרו, זמן ההתאוששות — שניות בודדות;
- תור לילי: הקיבולת גדלה יחד איתו ויורדת באותו אופן כשהזרימה נרגעת.
התוצאה מדידה: זמן ההתאוששות מתקצר מדקות לשניות, שיעור הכשלים מוגבל לגודל חלק הקנארי בתעבורה, והקיבולת עוקבת אחרי העומס בלי בזבוז על זמן עצירה.
מצבי סקיילינג ואסטרטגיות פרסום גרסאות
ב-Azure Container Apps הסקיילינג ופרסום הגרסאות נשענים על מנגנון אחד — רביזיות בלתי משתנות של האפליקציה. כל רביזיה מקבלת את חלקה בתעבורה, ולכן פריסת בנייה חדשה וחזרה לאחור מתבצעות בהחלפת משקלים, בלי בנייה מחדש ובלי השבתה.
הקיבולת נקבעת לפי חוקים: לפי עומס המעבד והזיכרון, לפי אורך התור, לפי לוח זמנים — עד סקיילינג עד אפס.
| אפשרות | מתי מתאים | מגבלות |
|---|---|---|
| מספר רפליקות קבוע | עומס יציב, שירותים פנימיים | לא שורד שיא, בזמן שקט המשאבים לא מנוצלים |
| חוקים לפי מטריקה | תעבורה משתנה, טיפול בתורים | תגובה בהשהיה, רגישות לסף, התנעה קרה |
| לוח זמנים | חלונות ידועים: שעות עבודה, משימות אצווה | פרץ לא מתוכנן מחוץ לחלון אינו מכוסה |
| פרסום לפי חלק מהתעבורה | בדיקת גרסה על חלק מהמשתמשים | שתי הגרסאות פעילות בו-זמנית: חוזי השירותים וסכימת הנתונים חייבים להיות תואמים |
| פרסום כחול-ירוק | שירות קריטי, נדרשת חזרה לאחור מיידית | כפילות משאבים בזמן ההחלפה |
מגבלה משותפת: תאימות נתונים
המגבלה המשותפת לכל האסטרטגיות — מצב. כל עוד התעבורה מתחלקת בין גרסאות, שינויי סכימה חייבים להיות תואמים לאחור: תחילה מוסיפים שדות וקוראים את שני הפורמטים, וישנים מסירים רק לאחר החלפה מלאה. אחרת חזרה לאחור תחזיר קוד שכבר לא מבין את הנתונים.
כיצד אנו מיישמים אוטוסקיילינג: שלבי העבודה
סדר העבודה נבנה מעומס מדוד לחוקים, ולא להפך: תחילה מצלמים פרופיל ביקוש ב-Azure Container Apps, אחר כך קובעים סכמת סקיילינג, ורק לאחר מכן מפעילים שינויים בסביבת הייצור. פער בין התנהגות השירות בבדיקות לבין הייצור הוא מקור רגיל להפעלות שווא.
- סקר עומס. מצלמים מטריקות במשך כמה שבועות: עוצמת בקשות, משך עיבוד, עומק תורים, צריכת משאבים בשיאים. לפיהן בוחרים טריגר שמשקף ביקוש אמיתי, ולא סימן עקיף.
- סכמת סקיילינג. מפרידים בין פרונטאנד, API ומעבדי רקע לקבוצות הניתנות לסקיילינג בנפרד, קובעים מינימום ומקסימום רפליקות ומפרידים סביבות, כדי שפיתוח לא יתחרה בייצור על קיבולת.
- הגדרת חוקים. מתארים טריגרים של KEDA — תור, זרימת אירועים, לוח זמנים — ומתאימים חלונות צינון עם צעד הגדלה, כדי שרפליקות לא יזוזו בפרצים קצרים. את החוקים שומרים כקוד ומעבירים אותם בביקורת.
- פריסת קנארי. מוציאים גרסה על חלק מהתעבורה, משווים שיעור שגיאות וזמן תגובה לבסיס, וחזרה לאחור מוגדרת אוטומטית לפי סף.
- בדיקות קבלה. מריצים את פרופיל העומס מהשלב הראשון עם שיאים מדורגים וכשל של תלות חיצונית: מודדים זמן עלייה לשיא, תקרת רפליקות וזמן חזרה.
- מסירה לתפעול. מוסרים קונפיגורציה במאגר, דשבורדים לפי רפליקות וטריגרים, התראות על הגעה לתקרה ועל כשלים, נוהל תורנות עם תרחישים טיפוסיים.
תצורות, סכמות ונוהלים לאחר ההטמעה
לאחר הוצאת השירות לייצור נשאר לצוות לא רק מתאר עובד, אלא גם מערך ארטיפקטים שלפיהם אפשר לשנות אותו בלעדינו.
הכול נמצא במאגר של הלקוח יחד עם היסטוריית השינויים: שינוי קונפיגורציה עובר ביקורת ומגיע לסביבה באותו מסלול כמו הקוד, ולכן ב-Azure Container Apps לא נוצרות הגדרות "בידיים דרך הקונסול". להלן מה בדיוק מוסרים.
- קונפיגורציית סקיילינג — חוקים וטווח רפליקות לכל שירות, ספי הפעלה לפי מטריקות, התנהגות בזמן שקט וזמן חימום לפני קבלת עומס.
- סכמת שירותים — קשרים בין רכיבים, נקודות כניסה, תורים ותלויות חיצוניות, עם גבול אחריות ברור בין האפליקציה לפלטפורמה.
- כללי גישה — תפקידים, זהויות שירות, מגבלות רשת וסדר הענקת הרשאות לרכיב או לקבלן חדש.
- נוהל פרסום — סדר פרסום קנארי: חלק התעבורה לרביזיה החדשה, מטריקות קריטריון לקידום ותנאי חזרה אוטומטית.
- הוראות חזרה לאחור — חזרה שלב-אחר-שלב לרביזיה הקודמת, כולל תאימות לסכימת נתונים ובדיקות לאחר החזרה לאחור.
- מפת ניטור — אילו מטריקות, לוגים והתראות הוגדרו, לאילו ספים הוגדרו ומי מקבל התראה בהפעלה.
- תזכורת לסביבות — במה נבדלות הסביבות, היכן מאוחסנים סודות ומשתנים, וכיצד להוסיף סביבה חדשה בלי לערוך תבניות.
מקרה בוחן: עומס שיא ללא התערבות ידנית
שירות הגשת בקשות ללקוחות ארגוניים החזיק שיא בסוף יום העבודה ובתחילת תקופת הדיווח: בשעה אחת הגיעו אותה כמות בקשות כמו בשאר היממה. הסקיילינג היה קשור לעומס המעבד, והוא גדל כבר אחרי שתור העיבוד התמלא.
בשיא שיעור הבקשות הכושלות הגיע ל-8%, זמן התגובה באחוזון ה-95 התארך לכמה שניות, והמהנדס התורן העלה רפליקות ידנית שלוש-ארבע פעמים ביממה.
האפליקציה הועברה ל-Azure Container Apps והסקיילינג הועבר למטריקות חיצוניות — אורך התור ומספר הבקשות במקביל במקום עומס המעבד. סף העלייה הוגדר עם מרווח, וכיבוי רפליקות — בהשהיה, כדי שירידה קצרה לא תסיר מופעים שכבר חוממו.
לפני ההפעלה הרצנו בדיקות עומס לפי העתק של שיא אמיתי: החזקנו פרופיל קיצון ובדקנו תוך כמה זמן מגיע מספר הרפליקות הנדרש ואיך מתנהג התור בירידה חדה. לפי התוצאות העלינו את מספר הרפליקות המינימלי והגדרנו חימום, כדי שהגל הראשון של הבקשות לא ייפול על התנעה קרה.
לאחר המעבר התורנויות הפכו מתוכננות — פעם בשבוע במקום שלוש-ארבע קריאות ביממה. שיעור הבקשות הכושלות ירד מ-8% ל-0.4%, זמן התגובה באחוזון ה-95 הצטמצם פי שלושה, והשיא מטופל ללא מעורבות מהנדס. הפריסה על חלק מהתעבורה נשארה מופעלת: חזרה לגרסה הקודמת אורכת דקות.
במה שונה אוטוסקיילינג ב-Azure מסקיילינג ידני
סקיילינג ידני מחזיק מספר רפליקות קבוע: הפלטפורמה לא מסתכלת על העומס עד שמהנדס משנה את הערך בעצמו. בזרימה יציבה זה צפוי, אבל פרץ — גידול בתור, השהיות, כשלים — רק התורן מטפל בו, ובשעות שקט אתם משלמים על משאבים לא מנוצלים.
סקיילינג לפי לוח זמנים מסיר חלק מהעבודה הידנית: החוק קובע כמה רפליקות להחזיק בשעות העבודה וכמה בלילה. זה עובד בפרופיל עומס חוזר ונשבר במבצעים חד-פעמיים.
| אפשרות | מתי מתאים | מגבלות |
|---|---|---|
| ידני | זרימה יציבה, דיבוג, שחרורים נדירים | תגובה רק מצד התורן |
| לפי לוח זמנים | שיאים יומיים ושבועיים חוזרים | לא רואה גידול לא מתוכנן |
| אירועי | תורים, זרמי בקשות, משימות אצווה | דרושים סף נכון וחלון התייצבות |
| משולב | בסיס צפוי ועוד פרצים | מורכב יותר להגדרה, דרושה בדיקת עומס |
סקיילינג אירועי נשען על מטריקה: אורך התור, מספר הבקשות במקביל, עומס המעבד. סף הסקיילינג וחלון ההתייצבות קובעים באיזה ערך מתווספת רפליקה וכמה זמן היא חיה לאחר הירידה — חלון צר יוצר "רעד", חלון רחב משאיר כוח עודף.
סכמה משולבת ב-Azure Container Apps מכסה את שני התרחישים: לוח הזמנים מוציא את הרמה הבסיסית לשיא הבוקר, וטריגר אירועי משלים רפליקות לפי העומס בפועל. אנו תחילה מצלמים פרופיל עומס, אחר כך מתאימים ספים ומאשרים אותם בבדיקת עומס — אחרת החוק נראה עובד, אבל לא פועל במקום הנדרש.
שאלות טכניות ששואלים לפני ההתחלה
לפני ההתחלה השאלות של צוות ההנדסה בדרך כלל אותו דבר: מה יקרה לחיבורים פעילים ברגע הפרסום, האם יהיה צורך לכתוב מחדש את האפליקציה, היכן הגבול העליון של הסקיילינג וכיצד המערכת מתנהגת כשמקור האירועים אינו זמין. להלן תשובות קצרות בלי שיווק, בדיוק כפי שאנו דנים בהן בסשן טכני.
מה יקרה לחיבורים פעילים בפרסום גרסה חדשה?
הפלטפורמה מעלה רביזיה חדשה לצד הישנה ומעבירה אליה חלק מהתעבורה. הישנה מכובה לא מיד, אלא לאחר שעיבוד הבקשות והחיבורים הפעילים מסתיים — אין ניתוקים בצד הלקוח.
אם הבדיקות לא עברו, משקל התעבורה חוזר אוטומטית לרביזיה הקודמת: חזרה אוטומטית לאחור מוגדרת מראש, ולא מופעלת ידנית ברגע התקלה.
האם צריך לכתוב מחדש את האפליקציה?
ברוב המקרים לא. האפליקציה נבנית לאותו קונטיינר כמו קודם, ומעליה מתווספים חוקים דקלרטיביים: לפי איזה אירוע לבצע סקיילינג, כמה רביזיות להחזיק, כיצד לפזר את התעבורה. שינויים נקודתיים נדרשים רק אם השירות עצמו מנהל חיבורים למקור האירועים או מחזיק מצב בזיכרון התהליך.
היכן הגבול העליון של הסקיילינג?
מוגדר במפורש: מספר מינימלי ומקסימלי של רפליקות ועוד חוק לפי מטריקה. זה הגנה מפני מפולת — בזמן פרץ העומס גדל באופן צפוי עד התקרה שהוגדרה, ולא עד למיצוי המכסה. אנו מתאימים את הגבולות לפי פרופיל העומס: כמה אירועים מגיעים בשיא, כמה מהר מעובד אירוע אחד, ואיזה מרווח נדרש לחימום.
מה לעשות אם מקור האירועים אינו זמין?
מפרידים בין שני מקרים — אי-זמינות של המקור ופיגור של התור. תולים ספים על אורך התור, ולא רק על האירועים עצמם, כדי שהסקיילינג יגיב להצטברות. התנהגות הרפליקות בעומס אפס גם מוגדרת: מעבר לאפס או החזקת מינימום, אם השירות צריך חימום.
נדון במשימת האוטוסקיילינג ופרסום גרסאות
כדי לחזור עם הערכה ותוכנית, ולא עם שיקולים כלליים, אנו צריכים מינימום נתוני קלט מהלקוח. להלן מה שאנו שואלים בשיחה הראשונה; בדרך כלל מספיקים חצי שעה של דיון וגישה למאגר עם מניפסטים וקונפיגורציית הפלטפורמה, כולל Azure Container Apps.
- פרופיל עומס: גרף יומי ושבועי, חלונות שיא, חלק המשימות ברקע ומחזוריות, פיזור הבקשות לפי פעולות.
- סכמת שירותים: אילו רכיבים לא מחזיקים מצב, אילו מחזיקים אותו בעצמם, מי מתקשר באופן סינכרוני ומי דרך תורים ואירועים.
- חוקי סקיילינג נוכחיים וצווארי בקבוק: כיצד המערכת מתנהגת בזמן פרץ, כמה זמן נמשכת הפעלה של מופע חדש, מה נתקע במגבלות הפלטפורמה.
- דרישות לפרסום גרסאות: חלק התעבורה לגרסת הקנארי, תנאי חזרה אוטומטית לאחור, חלון מותר של הידרדרות חלקית.
- הרשאות ומגבלות: סביבות, רשתות פרטיות, תפקידים, מדיניות אבטחה ונוהל שינויים בייצור.
- קבלת התוצאה: אילו מטריקות נחשבות יעד ובאילו תרחישים בודקים — פרץ חד, כשל מופע, חזרה לגרסה קודמת.
תארו את המשימה בצורה חופשית — נחזור עם הערכה, תוכנית עבודה ופירוק לשלבים. בשיחה נציג כיצד הפתרון מתאים לסכמת השירותים שלכם, ונתאם מראש את סדר קבלת התוצאה.







