פתרון בעיות שקשורות לזמן טעינה ארוך באפליקציות של App Engine

במקרים רבים, חביון גבוה באפליקציה מוביל בסופו של דבר לשגיאות שרת 5xx. יכול להיות שהסיבה הבסיסית לשגיאה ולעליות הפתאומיות בזמן האחזור היא אותה סיבה, ולכן כדאי לנסות את האסטרטגיות הבאות לפתרון בעיות שקשורות לזמן האחזור:

  1. הגדרת היקף הבעיה של זמן האחזור
  2. זיהוי הסיבה
  3. פתרון בעיות

הגדרת היקף הבעיה שקשורה לזמן האחזור

כדי להגדיר את היקף הבעיה, כדאי לשאול את השאלות הבאות:

  • אילו אפליקציות, שירותים וגרסאות מושפעים מהבעיה הזו?
  • אילו נקודות קצה ספציפיות בשירות מושפעות מהבעיה הזו?
  • האם הבעיה משפיעה על כל הלקוחות בעולם או על קבוצת משנה ספציפית של לקוחות?
  • מה שעת ההתחלה ושעת הסיום של האירוע? מומלץ לציין את אזור הזמן.
  • מהן השגיאות הספציפיות?
  • מהו שינוי ההשהיה שנצפה, שבדרך כלל מצוין כעלייה באחוזון מסוים? לדוגמה, זמן האחזור גדל ב-2 שניות באחוזון ה-90.
  • איך מדדת את זמן האחזור? באופן ספציפי, האם מדדתם את זה בצד הלקוח, או שזה מוצג ב-Cloud Logging או בנתוני ההשהיה של Cloud Monitoring שמסופקים על ידי תשתית ההגשה של App Engine?
  • מהם יחסי התלות של השירות שלך, והאם יש ביניהם כאלה שחווים אירועים?
  • האם ביצעת לאחרונה שינויים בקוד, בהגדרות או בעומס העבודה שגרמו לבעיה הזו?

יכול להיות שלשירות יש מערכת ניטור ורישום משלו, שאפשר להשתמש בה כדי לצמצם עוד יותר את היקף הבעיה. הגדרת היקף הבעיה תעזור לכם להבין מהו שורש הבעיה, ותקבע מה יהיו השלבים הבאים לפתרון הבעיה.

זיהוי הסיבה

קובעים איזה רכיב בנתיב הבקשה הוא כנראה הסיבה לחביון או לשגיאות. הרכיבים העיקריים בנתיב הבקשה הם:

לקוח --> אינטרנט --> ממשק הקצה של Google‏ (GFE)‏ --> תשתית שרתים של App Engine --> מופע שירות

אם המידע הקודם לא עוזר לכם להבין מהו המקור לבעיה, כדאי לנסות את האסטרטגיות הבאות כשאתם בודקים את התקינות והביצועים של מופע השירות:

  1. מעקב אחר יומני הבקשות של App Engine. אם מופיעות ביומנים האלה שגיאות של קוד סטטוס של HTTP או חביון גבוה, סביר להניח שהבעיה היא במופע שמריץ את השירות.

  2. אם מספר המופעים של השירות לא גדל בהתאם לרמות התנועה, יכול להיות שיהיה עומס יתר על המופעים, מה שיוביל לעלייה בשגיאות ובזמן האחזור.

  3. אם אתם רואים עלייה בשגיאות או בחביון ב-Cloud Monitoring, יכול להיות שהבעיה נובעת מהחלק שקודם למאזן העומסים, שמתעד את המדדים של App Engine. ברוב המקרים, זה מצביע על בעיה במופעי השירות.

  4. אם אתם רואים עלייה בערכי השהייה או שגיאות במדדי המעקב, אבל לא ביומני הבקשות, יכול להיות שמדובר בכשל באיזון העומסים או בכשל חמור במופע שמונע ממאזן העומסים לנתב בקשות. כדי להבחין בין המקרים האלה, כדאי לעיין ביומני הבקשות לפני תחילת האירוע. אם ביומני הבקשות מופיעה עלייה בערכי השהייה לפני הכשל, סימן שהמופעים של האפליקציה התחילו להיכשל לפני שמאזן העומסים הפסיק לנתב אליהם בקשות.

פתרון בעיות

בקטע הזה מתוארות אסטרטגיות לפתרון בעיות של השהיה מוגברת שנובעות מהרכיבים הבאים בנתיב הבקשה:

  1. אינטרנט
  2. ממשק הקצה של Google‏ (GFE)
  3. תשתית ההגשה של App Engine
  4. מופע של אפליקציה
  5. תלות באפליקציה

אינטרנט

יכול להיות שבאפליקציה שלך יהיו בעיות של זמן אחזור בגלל קישוריות לא טובה או רוחב פס נמוך.

חיבור לאינטרנט באיכות ירודה

כדי לבדוק אם הבעיה היא חיבור אינטרנט חלש, מריצים את הפקודה הבאה בלקוח:

$ curl -s -o /dev/null -w '%{time_connect}\n' <hostname>

הערך של time_connect מייצג את זמן הטעינה של החיבור של הלקוח לממשק קצה של Google‏ (GFE) הקרוב ביותר. בחיבורים איטיים, כדאי להשתמש ב-traceroute כדי לפתור בעיות ולזהות את הצעד ברשת שגורם לעיכוב.

מריצים בדיקות מלקוחות במיקומים גיאוגרפיים שונים. App Engine מנתב באופן אוטומטי בקשות למרכז הנתונים הקרוב ביותר של Google, שמשתנה בהתאם למיקום הלקוח.

רוחב פס נמוך

יכול להיות שהאפליקציה מגיבה במהירות, אבל צווארי בקבוק ברשת גורמים לעיכוב בשליחת מנות נתונים ברשת על ידי תשתית ההגשה של App Engine, וכך מאטים את התגובות.

ממשק קצה של Google‏ (GFE)

יכול להיות שבאפליקציה שלכם יהיו בעיות של זמן אחזור בגלל ניתוב שגוי, בקשות מקבילות שנשלחות מלקוחות HTTP/2 או סיום של חיבורי SSL.

מיפוי של כתובת IP של לקוח לאזור גיאוגרפי

‫Google מבצעת התאמת נתונים (resolve) של שם המארח של אפליקציית App Engine ל-GFE הקרוב ביותר ללקוח, על סמך כתובת ה-IP של הלקוח שבה נעשה שימוש בחיפוש DNS. אם מקודד ה-DNS של הלקוח לא משתמש בפרוטוקול EDNS0, יכול להיות ש-Google לא תנתב את בקשות הלקוח ל-GFE הקרוב ביותר.

חסימת HTTP/2 בראש התור

לקוחות HTTP/2 ששולחים כמה בקשות במקביל עשויים לראות השהיה מוגברת בגלל חסימה של בקשות בתור ב-GFE. כדי לפתור את הבעיה, הלקוחות צריכים להשתמש בפרוטוקול QUIC.

סיום SSL לדומיינים מותאמים אישית

יכול להיות ש-GFE יסיים את חיבור ה-SSL. אם אתם משתמשים בדומיין בהתאמה אישית במקום בדומיין appspot.com, נדרש עוד שלב כדי להשלים את סיום ה-SSL. יכול להיות שזה יוסיף זמן אחזור לאפליקציות שפועלות באזורים מסוימים. למידע נוסף, אפשר לעבור אל מיפוי דומיינים מותאמים אישית.

תשתית ההגשה של App Engine

יכול להיות שתהיה עלייה בחביון באפליקציה בגלל אירועים שמשפיעים על כל השירות או בגלל שינוי גודל אוטומטי.

אירועים שמשפיעים על כל השירות

‫Google מפרסמת פרטים על הפסקה זמנית חמורה בשירות בלוח הבקרה Service Health. עם זאת, Google מבצעת השקות בהדרגה, ולכן סביר להניח שאירוע שמשפיע על כל השירותים לא ישפיע על כל המקרים שלכם בבת אחת.

התאמה אוטומטית לעומס (Automatic scaling)

תרחישי התאמה אוטומטית לעומס שעלולים לגרום לזמן טעינה מוגבר או לשגיאות:

  • הגדלת נפח תעבורת הנתונים מהר מדי: יכול להיות שההתאמה האוטומטית לעומס של המכונות ב-App Engine לא תתבצע מהר מספיק בהתאם לעלייה בנפח תעבורת הנתונים, מה שיוביל לעומס יתר זמני. בדרך כלל, עומס יתר מתרחש כשתעבורת הנתונים נוצרת על ידי תוכנת מחשב ולא על ידי משתמשי קצה. כדי לפתור את הבעיה הזו, צריך לווסת נתונים את המערכת שיוצרת את תעבורת הנתונים.

  • עליות פתאומיות בתנועה: עליות פתאומיות בתנועה עלולות לגרום לזמני טעינה ארוכים יותר במקרים שבהם שירות עם שינוי גודל אוטומטי צריך להגדיל את הקיבולת שלו מהר יותר מהאפשר, בלי להשפיע על זמני הטעינה. בדרך כלל, תנועה של משתמשי קצה לא גורמת לעליות פתאומיות בתנועה בתדירות גבוהה. אם אתם רואים עליות פתאומיות בתנועה, כדאי לבדוק את הסיבה לכך. אם מערכת אצווה פועלת במרווחי זמן, יכול להיות שתוכלו להחליק את התנועה או להשתמש בהגדרות שונות של שינוי גודל.

  • הגדרות של שינוי גודל אוטומטי: אפשר להגדיר את שינוי הגודל האוטומטי על סמך מאפייני שינוי הגודל של השירות. יכול להיות שהפרמטרים של שינוי הגודל לא יהיו אופטימליים בתרחישים הבאים:

    • הגדרות קנה המידה של סביבת App Engine standard עלולות לגרום לזמן אחזור אם הן מוגדרות בצורה אגרסיבית מדי. אם ביומנים מופיעות תגובות שרת עם קוד הסטטוס 500 וההודעה 'הבקשה בוטלה אחרי המתנה ארוכה מדי לניסיון לטפל בבקשה שלך', המשמעות היא שחלף הזמן הקצוב לתגובה לבקשה בתור להמתנה בזמן ההמתנה למופע לא פעיל.

    • יכול להיות שתראו עלייה בזמן ההמתנה עם שינוי גודל ידני, גם אם הקציתם מספיק מופעים. אם האפליקציה שלכם משרתת תנועה של משתמשי קצה, מומלץ לא להשתמש בשינוי גודל ידני. שינוי גודל ידני מתאים יותר לעומסי עבודה כמו תורי משימות.

    • התאמת גודל בסיסית מצמצמת את העלויות על חשבון זמן האחזור. מומלץ לא להשתמש בהתאמת גודל בסיסית בשירותים שרגישים לזמן האחזור.

    • הגדרת ברירת המחדל של שינוי הגודל ב-App Engine מספקת חביון אופטימלי לרוב השירותים. אם עדיין רואים בקשות עם זמן המתנה ארוך, צריך לציין מספר מינימלי של מופעים. אם משנים את הגדרות שינוי הגודל כדי לצמצם עלויות על ידי מזעור של מופעים לא פעילים, קיים סיכון לעליות פתאומיות בחביון אם העומס גדל באופן פתאומי.

מומלץ להשוות את הביצועים עם הגדרות ברירת המחדל של שינוי הגודל, ואז להריץ השוואה חדשה אחרי כל שינוי בהגדרות האלה.

פריסות

עלייה בזמן האחזור זמן קצר אחרי הפריסה מצביעה על כך שלא הגדלתם את הקיבולת בצורה מספקת לפני העברת התנועה. יכול להיות שמופעים חדשים לא חיממו את המטמון המקומי, והם משרתים לאט יותר ממופעים ישנים.

כדי למנוע קפיצות בזמן האחזור, אל תפרסו שירות App Engine באמצעות אותו שם גרסה כמו גרסה קיימת של השירות. אם משתמשים בשם של גרסה קיימת, לא תהיה אפשרות להעביר את התנועה לגרסה החדשה בהדרגה. יכול להיות שהבקשות יהיו איטיות יותר כי App Engine מפעיל מחדש כל מופע תוך פרק זמן קצר. אם רוצים לחזור לגרסה הקודמת, צריך גם לפרוס מחדש.

מופע של אפליקציה

בקטע הזה מתוארות אסטרטגיות נפוצות שאפשר ליישם במקרים של אפליקציות ובקוד מקור כדי לשפר את הביצועים ולצמצם את זמן האחזור.

קוד אפליקציה

יכול להיות שיהיה קשה לנפות באגים בבעיות בקוד האפליקציה, במיוחד אם הן מתרחשות לסירוגין או שלא ניתן לשחזר אותן.

כדי לפתור את הבעיות:

  • כדי לאבחן את הבעיות, מומלץ להשתמש ברישום ביומן, במעקב וביומני מעקב כדי להוסיף לאפליקציה כלי מעקב. אפשר גם להשתמש ב-Cloud Profiler.

  • נסו לשחזר את הבעיה בסביבת פיתוח מקומית, שאולי תאפשר לכם להפעיל כלי ניפוי באגים ספציפיים לשפה, שאולי לא ניתן להפעיל ב-App Engine.

  • כדי להבין טוב יותר למה האפליקציה נכשלת ואיפה צווארי הבקבוק, כדאי לבצע בדיקת עומס באפליקציה עד שהיא נכשלת. מגדירים מספר מופעים מקסימלי, ואז מגדילים בהדרגה את העומס עד שהאפליקציה נכשלת.

  • אם הבעיה של זמן האחזור קשורה לפריסה של גרסה חדשה של קוד האפליקציה, כדאי לבצע החזרה לגרסה קודמת כדי לבדוק אם הגרסה החדשה גרמה לתקרית. עם זאת, אם אתם מבצעים פריסה רציפה, הפריסות התכופות מקשות על קביעה אם הפריסה גרמה לאירוע על סמך זמן ההתחלה.

  • יכול להיות שהאפליקציה שלכם שומרת הגדרות תצורה ב-Datastore או במקום אחר. יוצרים ציר זמן של שינויים בהגדרות כדי לבדוק אם יש שינויים שחלו בסמוך לתחילת העלייה בחביון.

שינוי בעומס העבודה

שינוי בעומס העבודה עלול לגרום לזמן אחזור מוגבר. חלק ממדדי המעקב שמצביעים על שינויים בעומס העבודה כוללים את qps, השימוש ב-API וזמן האחזור. כדאי גם לבדוק אם יש שינויים בגודל הבקשה והתגובה.

עומס על הזיכרון

אם המעקב מראה דפוס של שיני מסור בשימוש בזיכרון, או ירידה בשימוש בזיכרון שקשורה לפריסות, יכול להיות שדליפת זיכרון היא הגורם לבעיות בביצועים. דליפת זיכרון עלולה גם לגרום ל-garbage collection תכוף, מה שמוביל לזמן אחזור גבוה יותר. אם לא הצלחתם לאתר את הבעיה בקוד, נסו להקצות מופעים גדולים יותר עם יותר זיכרון.

דליפת משאבים

אם מופע של האפליקציה שלכם מציג עלייה בחביון שקשורה לגיל המופע, יכול להיות שיש לכם דליפת משאבים שגורמת לבעיות בביצועים. החביון יורד אחרי שהפריסה מסתיימת. לדוגמה, מבנה נתונים שפועל לאט יותר לאורך זמן בגלל שימוש גבוה יותר במעבד, עלול לגרום לעומסי עבודה שמוגבלים על ידי המעבד לפעול לאט יותר.

אופטימיזציה של הקוד

כדי להקטין את זמן האחזור ב-App Engine, צריך לבצע אופטימיזציה של הקוד באמצעות השיטות הבאות:

  • עבודה אופליין: אפשר להשתמש ב-Cloud Tasks כדי למנוע מבקשות של משתמשים לחסום את האפליקציה בזמן שהיא ממתינה להשלמת העבודה, כמו שליחת אימייל.

  • קריאות אסינכרוניות ל-API: מוודאים שהקוד לא נחסם בהמתנה להשלמת קריאה ל-API.

  • קריאות מקובצות ל-API: הגרסה המקובצת של קריאות ל-API בדרך כלל מהירה יותר משליחת קריאות בנפרד.

  • ביטול הנרמול של מודלים של נתונים: כדי לצמצם את זמן האחזור של קריאות שמתבצעות לשכבת שמירת הנתונים, מבטלים את הנרמול של מודלים של נתונים.

יחסי תלות של אפליקציות

עליכם לעקוב אחרי יחסי התלות של האפליקציה כדי לזהות אם יש קורלציה בין קפיצות בזמן האחזור לבין כשל ביחסי התלות.

שינוי בעומס העבודה (workload) ועלייה בתנועה עשויים לגרום לעלייה בחביון של תלות.

תלות שלא ניתנת להרחבה

אם התלות של האפליקציה לא גדלה ככל שמספר המופעים של App Engine גדל, יכול להיות שהתלות תגרום לעומס יתר כשתנועת הגולשים תגדל. דוגמה לתלות שלא ניתנת להרחבה היא מסד נתונים של SQL. מספר גבוה יותר של מופעי אפליקציה מוביל למספר גבוה יותר של חיבורים למסד הנתונים, מה שעלול לגרום לכשל מדורג ולמנוע את הפעלת מסד הנתונים. כדי לפתור את הבעיה:

  1. פורסים גרסת ברירת מחדל חדשה שלא מתחברת למסד הנתונים.
  2. משביתים את גרסת ברירת המחדל הקודמת.
  3. פריסת גרסה חדשה שלא מוגדרת כברירת מחדל, שמתחברת למסד הנתונים.
  4. מעבירים את התנועה בהדרגה לגרסה החדשה.

כאמצעי מניעה, כדאי לתכנן את האפליקציה כך שתבטל בקשות לתלות באמצעות הגבלת קצב דינמית.

כשל בשכבת המטמון

כדי לזרז את הבקשות, כדאי להשתמש בכמה שכבות של שמירה במטמון, כמו שמירה במטמון בקצה הרשת, Memcache וזיכרון במופע. תקלה באחת משכבות ה-Caching האלה עלולה לגרום לעלייה פתאומית בזמן האחזור. לדוגמה, ניקוי של Memcache עשוי לגרום ליותר בקשות להישלח אל Datastore איטי יותר.