Serverless ו-Edge Functions: היכן נשבר הבקאנד הקלאסי
צוואר הבקבוק הגדול ביותר בעיבוד בקשות מתגלה לא ביום ממוצע, אלא בשיא העומס. בקאנד שרת קלאסי מחושב לפי עומס שיא: מאגר ה-workers, החיבורים והזיכרון מוחזקים עם מרווח לקפיצות נדירות, וכל שאר הזמן המרווח הזה עומד ללא שימוש. ברגע שהתעבורה קופצת פי כמה, המטפלים הפנויים נגמרים — מתחיל עומס יתר בשיאים.
מכאן פועל אפקט מצטבר: תור הבקשות גדל, ההידרדרות בתגובה מתגלגלת כמפולת — זמן התגובה עובר משברירי שנייה לשניות, האחוזון ה-95 מזנק למעלה, וחלק מהפניות נופל בטיים-אאוט עוד לפני הכניסה ללוגיקה העסקית. המשתמש רואה לא «איטי», אלא «לא עובד», ועוזב. עבור בעל השירות מדובר בהזמנות שאבדו, ולא בשורה בלוגים, ומתחילים להתעמק בה רק אחרי התקרית.
Scaling אוטומטי אופקי מכסה זאת רק באופן חלקי: מופע חדש עולה תוך דקות, מחמם מטמון ופותח חיבורים למסד נתונים שיש לו גבול משלו — כשאנחנו מרחיבים את האפליקציה, אנחנו נתקלים במאגר החיבורים ובנעילות משותפות. השיא מספיק לחלוף לפני שהתשתית מגיבה אליו.
Serverless ו-Edge Functions מסירים בדיוק את המגבלה הזו: המטפל מופעל עבור כל בקשה ומתרחב בהתאם לעומס בפועל, ללא חימום וללא רזרבה קבועה. להלן נבחן כיצד זה נסגר בפועל — והיכן הבקאנד הקלאסי עדיין נותר הבחירה הנכונה.
מה נותן עיבוד בקשות פריפריאלי
עיבוד פריפריאלי מעביר את ביצוע הלוגיקה קרוב יותר למבקר: המטפל מופעל על צומת רשת בקרבתו, ולא במרכז עיבוד נתונים יחיד. להלן ארבעה אפקטים שנראים במטריקות, ולא בניסוחים.
זמן תגובה בבקשות מבוזרות
חלק ניכר מזמן התגובה אינו חישובים, אלא סבבי רשת בין המבקר לשרת. כאשר הפונקציה מבוצעת על הצומת הקרוב ביותר, כל סבב מתקצר, ובשרשרת של כמה פניות זה מצטבר להבדל מורגש עבור המשתמש.
מדידות עצמאיות של השהיות בין אזורים מפרסם M-Lab — את המדידות הפתוחות שלהם נוח לקחת כנקודת ייחוס בעת בחירת מקום אחסון המטפלים.
מחלקות כשל שהוסרו בעומס שיא
תור של בקשות נכנסות, מיצוי מאגר החיבורים למסד הנתונים, נפילה של אתר שלם — בסכימה פריפריאלית מחלקות כשל אלו מפסיקות להיות מערכתיות. כאשר צומת בודד מתדרדר, התעבורה עוברת לשכן, וההשבתה נמדדת בשניות, ולא בזמן של מיתוג ידני של הכתיבה.
ההתרחבות לשיאים מוטלת על הפלטפורמה: מופעי מטפלים נוספים לפי הזרימה בפועל ומוסרים כשהיא דועכת. רזרבה קבועה ליום הגרוע בשבוע אינה נדרשת עוד — היא הופכת למרווח במכסות.
שרת ייעודי, Serverless ופונקציות פריפריאליות: השוואה
מודל ההרצה קובע שלושה דברים: כיצד האפליקציה שורדת שיא עומס, כמה זמן לוקח להוציא שינוי ואילו כשלים בכלל אפשריים. שרת ייעודי הוא צפוי, אך עומד ללא שימוש בירידות; פונקציות פריפריאליות מגיבות מהר, אך חיות בסביבה מצומצמת. הבחירה כאן אינה בשאלה «מה מודרני יותר», אלא במה שנתקל במגבלה במקרה שלכם.
להלן האלטרנטיבות שביניהן באמת בוחרים בשלב התכנון, והמגבלות שלהן.
| אפשרות | מתי מתאימה | מגבלות |
|---|---|---|
| שרת ייעודי קבוע | זרימה יציבה, חיבורים ארוכים, משימות רקע | השבתה בירידות, התרחבות ידנית, עדכונים עליכם |
| קונטיינר | נדרש שליטה על הסביבה ללא תלות בחומרה | התנעה קרה, נדרשים אורקסטרטור ומגבלות |
| פונקציות שרת | עומס מקוטע, וובהוקים, עיבוד אירועים | מגבלת זמן ריצה, אין מצב קבוע |
| פונקציות פריפריאליות | התאמה אישית, ניתוב, תגובה קרובה יותר למשתמש | סביבה מצומצמת, מגבלות זיכרון, אין ספריות כבדות |
| סכימה היברידית | חזית על פונקציות, ליבה ותורים — על השרת | דיבוג וטראסינג מורכבים יותר, נדרשים כללי שחרור אחידים |
מתי משתלמת סכימה היברידית
לסכימה היברידית יש היגיון כאשר לאפליקציה שני פרופילי עומס שונים: תגובה לפעולת משתמש ועיבוד רקע. את החזית, האימות והניתוב מוסרים לפונקציות פריפריאליות, אירועים ותורים — לפונקציות שרת, ואת מסד הנתונים, החיפוש והחישובים הכבדים מחזיקים בשרת קבוע או בקונטיינרים. הגבול עובר לפי מצב: ככל שהפונקציה קרובה יותר לנתונים, כך קטן הרווח מהעברתה החוצה.
כיצד אנו פורסים לוגיקת שרת: שלבי העבודה
פריסת לוגיקת שרת מתחילה לא בקוד, אלא במיפוי מה שכבר עובד. אנחנו מצלמים פרופיל עומס על תעבורה אמיתית: אילו נתיבים נקראים בתדירות הגבוהה ביותר, היכן מוחזק החיבור למסד הנתונים, אילו פעולות נתקלות בהתנעה קרה. רק לאחר מכן מחליטים מה עובר לפונקציות מנוהלות ומה נשאר בתהליכים קבועים.
אודיט וסכימה
- אודיט בקאנד ופרופיל עומס — מפת מטפלים, בקשות שיא, משך התגובה, שיעור הפניות החוזרות. המספרים מראים היכן הפונקציה מחזירה את עצמה והיכן תוסיף השהיה.
- סכימת פריסה — מפרסים את הנתיבים לפי אזורי הרצה, מתעדים נקודות כשל והתנהגות האפליקציה כאשר שירות חיצוני אינו זמין.
- הגדרת סביבות ומסדי נתונים — קונטורים נפרדים, סדר המיגרציות, הרשאות וסודות מחוץ לריפוזיטורי, מגבלות זמן ריצה לכל פונקציה.
הגדרה, בדיקה, מסירה
- העברת לוגיקה וחיבור מאגרי נתונים — בשלבים ועם תאימות לאחור: הקונטור הישן והחדש פועלים במקביל, והתעבורה מנותבת במנות.
- בדיקת עומס וכשל — הרצה על הפרופיל שנלכד בשלב הראשון, בתוספת ניתוק מסד הנתונים והשירותים החיצוניים. בודקים כיצד התור מתאושש והאם אירועים הולכים לאיבוד.
- העלאה לפרודקשן ומסירה — מפעילים נראות, התראות על שגיאות והשהיות, מוסרים סכימה, קונפיגורציות ונוהל רולבק.
מה נשאר בריפוזיטורי שלכם לאחר המסירה
לאחר ההשקה הפרויקט נשאר אצלכם לא «קופסה שחורה», אלא כריפוזיטורי פעיל שנקרא ומשוחזר על ידי הצוות שלכם. הדבר נכון גם לאפליקציות על פונקציות (Serverless ו-Edge Functions): אנחנו מוסרים לא אוסף קבצים «כפי שיצא», אלא תיאור של הסביבה, הקשרים וכללי התפעול.
להלן המינימום ההכרחי שעובר אליכם בעת המסירה:
- קונפיגורציות סביבה — פיתוח, קונטור בדיקות, סביבת עבודה: אותו קוד בדיוק נפרס באופן צפוי, וההבדלים הם רק בפרמטרים.
- סכימות ניתוב בקשות — איזה נתיב ודומיין מוביל לאן, היכן מופעל המטמון, אילו כללים פועלים על הצומת הקרוב למשתמש ואילו בצד השרת.
- מדיניות גישה ותפקידים — מי ומה יכול לשנות, כיצד מנפיקים ומבטלים מפתחות, כיצד מופרדות ההרשאות של הצוות שלכם ושל הצוות הקבלני.
- תיאור משתני סביבה — טבלה עם הייעוד של כל אחד, האם הוא חובה, פורמט הערך ורשימת המקומות שבהם הוא משמש.
- תיעוד — הרצה מקומית, הרכב השירותים, נקודות אינטגרציה, סדר שחרור גרסה חדשה וסימנים לתקלות אופייניות.
- נוהל עדכון ורולבק — כיצד לשחרר שינוי וכיצד לחזור לגרסה הקודמת, ומה קורה בזמן הזה לנתונים.
סכימות ונהלים
הסכימות נשמרות לצד הקוד ומתעדכנות יחד איתו, ולא חיות בהתכתבות. נוהל העדכון והרולבק נבדק על קונטור הבדיקות לפני המסירה: מהנדס שלא נגע בפרויקט קודם לכן מרים עותק של הסביבה ומבצע רולבק לשחרור לפי המסמך, ללא הבהרות מצידנו.
מקרה בוחן: עומס שיא בזמן מבצעים
הלקוח — חנות קמעונאית עם שיאים חדים: בימי מבצעים זרימת הפניות גדלה פי עשרה בתוך שעה. החזית פעלה על שני שרתים עם תקרה קבועה, ובחריגה ממנה הקטלוג החל להחזיר שגיאות, העגלה איבדה פריטים, והמהנדסים הרימו צמתים חדשים ידנית וחיכו לחימום המטמון.
הוספת שרתים «ערב לפני» לא עזרה: אי אפשר לנחש את הדקה המדויקת של השיא, חלק מהמשאבים עמד ללא שימוש, וחלק לא הספיק להיכנס לפעולה. ניתחנו היכן בדיוק אבד הזמן בנתיב הבקשה, ופיזרנו מחדש את העומס לפי שכבות.
מטריקות לפני ואחרי
| מדד | לפני | אחרי |
|---|---|---|
| זמן תגובת הקטלוג בשיא | שניות, עם עלייה בכל דקה של הקפיצה | עשיריות שנייה יציבות |
| שיעור השגיאות בקפיצה פי עשרה | כ-4% מהבקשות | מתחת ל-0.1% |
| זמן ההתאוששות לאחר תקלה | שעות של פעולות ידניות | דקות, אוטומטית |
| ההיערכות למבצע | עבודות לילה עם עצירת החזית | ללא עצירה, בשלבים |
את החזית והבלוקים המותאמים אישית מוסרים קרוב יותר למשתמש, ואת ביצוע ההזמנה, התשלום והמיילים הוצאנו לעיבוד אסינכרוני עם תור וחזרות. מופעים חדשים של האפליקציה עולים תוך שניות, ולכן הקפיצה פי עשרה נבלמת מעצמה, ללא תורנות ליד המסכים.
סדר הגודל מאושר במדידות פומביות: Cloudflare מפרסם סטטיסטיקה פתוחה על ההבדל בין תגובה מהפריפריה לבין תגובה ממרכז אחד — radar.cloudflare.com. עבור הלקוח משמעות הדבר היא שהמבצע חדל להיות מצב חירום: האפליקציה מחזיקה את השיא, והצוות עוסק בפיתוח ולא בכיבוי שריפות.
במה נבדלת פונקציה פריפריאלית מפונקציית שרת
נקודת ההרצה של הקוד נקבעת על ידי הפלטפורמה, ולא על ידי הקוד. פונקציית שרת נפרסת באזור נבחר: בקשת המשתמש עוברת ברשת עד אותו אזור ורק שם מתחילה להיות מעובדת.
פונקציה פריפריאלית מבוצעת בצומת הקרוב ביותר למשתמש — הנתיב ברשת מתקצר ממאות מילישניות לעשרות, וזה נראה בזמן עד הבית הראשון של התגובה.
זמן ההפעלה שלהן שונה מטבעו. פונקציית שרת חיה בקונטיינר שהפלטפורמה עוצרת בזמן חוסר פעילות: הבקשה הראשונה לאחר הפסקה מקבלת התנעה קרה ומוסיפה לתגובה עשרות ומאות מילישניות.
סביבות פריפריאליות מחזיקות את ה-isolates חמים, ולכן ההפעלה שם נמדדת ביחידות מילישניות, אך בתמורה למגבלות נוקשות על משך ההרצה ונפח הזיכרון.
נתונים בקרבת המשתמש — רק קלים: כותרות הבקשה, נתונים גאוגרפיים לפי כתובת, מטמון של סטטיקה, רפליקות של מאגרי מפתח-ערך. מסד הנתונים הראשי נשאר באזור, ואם הפונקציה הפריפריאלית מבצעת אליו בקשה סינכרונית, הרווח בהשהיה נאכל בדרך חזרה. לכן ההחלטה מתקבלת לפי נתונים, ולא לפי טעם.
לפריפריה לא מוציאים חישובים ארוכים, טרנזקציות עם כמה כתיבות, עבודה עם קבצים ומשימות רקע. תלויות כבדות ומודולים נייטיביים מגדילים את גודל הבילד וזמן ההפעלה, ומצב בין בקשות אינו נשמר שם באופן צפוי. לוגיקה עסקית, גישה למסד הנתונים ואינטגרציות נשארות בפונקציות שרת.
בפריפריה מחזיקים בדיקת טוקן, רידיירקטים, התאמה אישית של כותרות, הגשת מטמון ופיצול תעבורה. הגבול עובר לפי סימן פשוט: אם התגובה נבנית מנתונים שנמצאים בקרבת המשתמש — זו פריפריה; אם נדרש קונטקסט מלא ממסד הנתונים — זו פונקציית שרת.
ספקות טכניים לפני ההתחלה
הספקות בהתחלה כמעט תמיד זהים — ומוצדקים. את חמש השאלות שלהלן אנו מבררים לפני השורה הראשונה של הקונפיגורציה: במודל serverless דווקא התשובות להן קובעות את הארכיטקטורה, ולא להיפך.
האם נוכל להחזיר את העומס לשרת קבוע?
כן, את ההעברה ההפוכה מתכננים מראש: הלוגיקה חיה במטפלים ניידים, והעבודה עם מאגר הנתונים מתבצעת דרך ממשקים משלנו. המעבר אורך ימים, ולא חודשים.
האם אפשר להריץ בהיברידי — להשאיר חלק מהנתיבים אצלנו?
כן. את האדמין, הדוחות ומשימות הרקע הכבדות מחזיקים על שרתים קבועים, ולפריפריה מוסרים את העמודים הציבוריים ואת המטפלים של אירועים חיצוניים.
היכן נשמרים המפתחות והסודות?
במאגר מאובטח, ההזרקה — ברגע הקריאה: הם לא נכנסים לריפוזיטורי ולמשתני הבילד. גישה לפי תפקידים, רוטציה של מפתחות, יומן פניות.
כיצד האפליקציה עובדת עם מסד הנתונים מאזורים שונים?
קריאה — מהרפליקה הקרובה, כתיבה — למסד הראשי, החיבורים עוברים דרך מאגר. עבור פעולות עם עקביות מחמירה משאירים אזור אחד — מגבלה זו מפורשת מראש לפני ההתחלה.
מי אחראי על רולבק של שינויים?
אנחנו. הגרסאות בלתי ניתנות לשינוי ומתויגות, הרולבק — מיתוג התעבורה לקודמת תוך דקות. סכימת מסד הנתונים משתנה רק עם מיגרציות הפוכות שנבדקו על עותק.
נדון במשימה ונחזור עם הערכה
כדי שההערכה תישען על הקונטור שלכם ולא על תבנית גנרית, די במערכת ראשונית של נתוני פתיחה — חלק מהנתונים נמצאים בדרך כלל כבר בריפוזיטורי ובפאנל הנראות. שלחו את מה שיש בהישג יד, את השאר נברר בשיחה.
- סכימה של הבקאנד הנוכחי: אילו שירותים קיימים, מה חי בתהליך אחד, היכן נשמר המצב המשותף;
- פרופיל עומס: בקשות שיא לשנייה, קצב יומי ושבועי, קפיצות עונתיות;
- רשימת נתיבים ואופיים: הגשת סטטיקה, קריאה ממסד הנתונים, חישובים כבדים, פניות למערכות חיצוניות;
- מגבלות על נתונים: היכן מותר להם להיות, דרישות להצפנה, לתקופות שמירה ולמחיקה;
- דרישות זמינות: זמן אי-זמינות מותר ועדיפות בין אזורים;
- מגבלות חיצוניות: מה אסור לשנות בחוזים עבור לקוחות מובייל ואינטגרציות שותפים;
- הרשאות גישה: ריפוזיטורי, סביבת בדיקות, פאנל נראות, הרשאות קריאה של סכימות קונפיגורציה.
לפי נתוני הפתיחה הללו נבחן אילו נתיבים מועברים לקונטור ללא-שרת ולחישובים בקצה הרשת, ואילו נשארים בתהליכים קבועים — בדרך כלל אלו משימות רקע וחיבורים ארוכים. נחזור עם הערכת העבודה ותוכנית הטמעה: סדר ההעברה, נקודות רולבק בכל שלב, הרכב הבדיקות וסדר מיתוג התעבורה. תארו את המשימה — נדון בפרטים ונתאם שיחה.







