במקרים רבים, חביון גבוה באפליקציה מוביל בסופו של דבר לשגיאות שרת 5xx. יכול להיות שהסיבה הבסיסית לשגיאה ולעליות הפתאומיות בזמן האחזור היא אותה סיבה, ולכן כדאי לנסות את האסטרטגיות הבאות לפתרון בעיות שקשורות לזמן האחזור:
הגדרת היקף הבעיה של זמן האחזור
כדי להגדיר את היקף הבעיה, כדאי לשאול את השאלות הבאות:
- אילו אפליקציות, שירותים וגרסאות מושפעים מהבעיה הזו?
- אילו נקודות קצה ספציפיות בשירות מושפעות מהבעיה הזו?
- האם השינוי משפיע על כל הלקוחות בעולם או על קבוצת משנה ספציפית של לקוחות?
- מה שעת ההתחלה ושעת הסיום של האירוע? כדאי לציין את אזור הזמן.
- מהן השגיאות הספציפיות?
- מהו דלתא ההשהיה שנצפה, שבדרך כלל מצוין כעלייה באחוזון ספציפי? לדוגמה, זמן האחזור גדל ב-2 שניות באחוזון ה-90.
- איך מדדת את זמן האחזור? באופן ספציפי, האם מדדתם את זה בצד הלקוח, או שזה מופיע ב-Cloud Logging או בנתוני ההשהיה של Cloud Monitoring שמסופקים על ידי תשתית ההגשה של App Engine?
- מהם יחסי התלות של השירות שלך, והאם יש ביניהם כאלה שחווים אירועים?
- האם ביצעת לאחרונה שינויים בקוד, בתצורה או בעומס העבודה שגרמו לבעיה הזו?
יכול להיות שלשירות יש מערכת משלו לניטור ולרישום ביומן, שתוכלו להשתמש בה כדי לצמצם עוד יותר את היקף הבעיה. הגדרת היקף הבעיה תעזור לכם להבין מהו שורש הבעיה ותקבע מהם השלבים הבאים לפתרון הבעיה.
זיהוי הסיבה
קובעים איזה רכיב בנתיב הבקשה הוא כנראה הסיבה לחביון או לשגיאות. הרכיבים העיקריים בנתיב הבקשה הם:
לקוח --> אינטרנט --> ממשק הקצה של Google (GFE) --> תשתית שרתים של App Engine --> מופע שירות
אם המידע הקודם לא עוזר לכם להבין מה מקור הכשל, כדאי להשתמש באסטרטגיות הבאות כשבודקים את התקינות והביצועים של מופע השירות:
עוקבים אחרי יומני הבקשות של App Engine. אם מופיעות ביומנים האלה שגיאות של קוד סטטוס של HTTP או חביון גבוה, סביר להניח שהבעיה היא במופע שמריץ את השירות.
אם מספר המופעים של השירות לא גדל בהתאם לרמות התנועה, יכול להיות שיהיה עומס יתר על המופעים, מה שיגרום לעלייה בשגיאות ובזמן האחזור.
אם אתם רואים עלייה בשגיאות או בחביון ב-Cloud Monitoring, יכול להיות שהבעיה נובעת מהחלק שקודם למאזן העומסים, שמתעד את המדדים של App Engine. ברוב המקרים, זה מצביע על בעיה במופעי השירות.
אם אתם רואים חביון גבוה או שגיאות במדדי המעקב, אבל לא ביומני הבקשות, יכול להיות שיש כשל באיזון העומסים או כשל חמור במופע שמונע ממאזן העומסים לנתב בקשות. כדי להבחין בין המקרים האלה, צריך לעיין ביומני הבקשות לפני שהאירוע מתחיל. אם יומני הבקשות מראים עלייה בזמן האחזור לפני הכשל, מופעי האפליקציה התחילו להיכשל לפני שמאזן העומסים הפסיק להפנות אליהם בקשות.
פתרון בעיות
בקטע הזה מתוארות אסטרטגיות לפתרון בעיות של השהיה מוגברת ברכיבים הבאים בנתיב הבקשה:
אינטרנט
יכול להיות שבאפליקציה שלך יהיו בעיות של זמן אחזור בגלל קישוריות לא טובה או רוחב פס נמוך.
חיבור לאינטרנט באיכות ירודה
כדי לבדוק אם הבעיה היא חיבור אינטרנט חלש, מריצים את הפקודה הבאה בלקוח:
$ curl -s -o /dev/null -w '%{time_connect}\n' <hostname>
הערך של time_connect מייצג את זמן האחזור של החיבור של הלקוח ל-Google Front End הקרוב ביותר.
אם החיבור איטי, אפשר להשתמש ב-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 לא תגדיל את מספר המופעים מהר מספיק בהתאם לעלייה בנפח התנועה, ולכן ייווצר עומס זמני. בדרך כלל, עומס יתר מתרחש כשתוכנת מחשב יוצרת תנועה במקום משתמשי קצה. כדי לפתור את הבעיה, צריך לווסת את קצב התעבורה של המערכת שמייצרת את התעבורה.
עליות חדות בתנועה: עליות חדות בתנועה עלולות לגרום לזמן אחזור גבוה יותר במקרים שבהם שירות עם התאמה אוטומטית לעומס צריך להגדיל את הקיבולת שלו מהר יותר מהאפשר, בלי להשפיע על זמן האחזור. בדרך כלל, תנועה של משתמשי קצה לא גורמת לעליות פתאומיות תכופות בתנועה. אם אתם רואים עליות חדות בתנועה, כדאי לבדוק מה הסיבה לכך. אם מערכת אצווה פועלת במרווחי זמן, יכול להיות שאפשר להחליק את התעבורה או להשתמש בהגדרות שונות של קנה מידה.
הגדרות של Autoscaler: אפשר להגדיר את Autoscaler על סמך מאפייני ההתאמה של השירות. יכול להיות שהפרמטרים של שינוי הגודל לא יהיו אופטימליים בתרחישים הבאים:
הגדרות ההתאמה לעומס בסביבה הרגילה של App Engine עלולות לגרום לזמן אחזור אם הן מוגדרות בצורה אגרסיבית מדי. אם אתם רואים ביומנים תגובות מהשרת עם קוד הסטטוס
500וההודעה "הבקשה בוטלה אחרי המתנה ארוכה מדי לניסיון לטפל בבקשה שלך", המשמעות היא שחלף הזמן הקצוב לתגובה לבקשה בתור להמתנה בזמן שהמערכת חיפשה מופע בלי פעילות.יכול להיות שתראו עלייה בזמן ההמתנה עם שינוי גודל ידני, גם אם הקציתם מספיק מופעים. אם האפליקציה שלכם משרתת תנועה של משתמשי קצה, מומלץ לא להשתמש בשינוי גודל ידני. שינוי גודל ידני מתאים יותר לעומסי עבודה כמו תורי משימות.
שינוי גודל בסיסי ממזער את העלויות על חשבון זמן האחזור. מומלץ לא להשתמש בהתאמת גודל בסיסית בשירותים שרגישים לזמן האחזור.
הגדרת ברירת המחדל של קנה המידה ב-App Engine מספקת חביון אופטימלי לרוב השירותים. אם עדיין רואים בקשות עם זמן המתנה גבוה, צריך לציין מספר מינימלי של מופעים. אם משנים את הגדרות ההתאמה כדי לצמצם עלויות על ידי מזעור של מופעים לא פעילים, קיים סיכון לעליות פתאומיות בזמן האחזור אם העומס גדל באופן פתאומי.
מומלץ להשוות את הביצועים עם הגדרות ברירת המחדל של שינוי הגודל, ואז להריץ השוואה חדשה אחרי כל שינוי בהגדרות האלה.
פריסות
עלייה בזמן האחזור זמן קצר אחרי פריסה מצביעה על כך שלא הגדלתם את הקיבולת בצורה מספקת לפני העברת התנועה. יכול להיות שבמופעים חדשים יותר המטמון המקומי לא חומם, והם פועלים לאט יותר ממופעים ישנים יותר.
כדי למנוע קפיצות בערכי השהייה, אל תפרסו שירות App Engine באמצעות אותו שם גרסה כמו גרסה קיימת של השירות. אם משתמשים בשם של גרסה קיימת, לא ניתן להעביר את התנועה לגרסה החדשה בהדרגה. יכול להיות שהבקשות יהיו איטיות יותר כי App Engine מפעיל מחדש כל מופע תוך פרק זמן קצר. אם רוצים לחזור לגרסה הקודמת, צריך גם לפרוס מחדש.
מופע של אפליקציה
בקטע הזה מתוארות אסטרטגיות נפוצות שאפשר ליישם במקרים של אפליקציות ובקוד מקור כדי לשפר את הביצועים ולהפחית את זמן האחזור.
קוד אפליקציה
יכול להיות שיהיה קשה לאתר באגים בבעיות בקוד האפליקציה, במיוחד אם הן מתרחשות לסירוגין או שלא ניתן לשחזר אותן.
כדי לפתור את הבעיות:
כדי לאבחן את הבעיות, מומלץ להטמיע באפליקציה רישום ביומן, מעקב ויומני מעקב. אפשר גם להשתמש ב-Cloud Profiler.
נסו לשחזר את הבעיה בסביבת פיתוח מקומית, שאולי תאפשר לכם להפעיל כלים לניפוי באגים שספציפיים לשפה, שלא ניתן להפעיל ב-App Engine.
כדי להבין טוב יותר איך האפליקציה נכשלת ואילו צווארי בקבוק מתרחשים, כדאי לבצע בדיקת עומס באפליקציה עד שהיא נכשלת. מגדירים מספר מופעים מקסימלי, ואז מגדילים בהדרגה את העומס עד שהאפליקציה נכשלת.
אם הבעיה של זמן האחזור קשורה לפריסה של גרסה חדשה של קוד האפליקציה, כדאי לבצע החזרה לגרסה קודמת כדי לבדוק אם הגרסה החדשה גרמה לתקרית. עם זאת, אם אתם מבצעים פריסה באופן רציף, קשה לקבוע אם הפריסה גרמה לאירוע על סמך שעת ההתחלה.
יכול להיות שהאפליקציה שלכם מאחסנת הגדרות תצורה ב-Datastore או במקום אחר. יוצרים ציר זמן של שינויים בהגדרות כדי לבדוק אם יש התאמה בין השינויים לבין תחילת העלייה בחביון.
שינוי בעומס העבודה
שינוי בעומס העבודה (workload) עלול לגרום לזמן אחזור ארוך יותר. חלק ממדדי הניטור שמצביעים על שינויים בעומס העבודה כוללים את qps, השימוש ב-API והחביון. כדאי גם לבדוק אם יש שינויים בגודל הבקשה והתשובה.
עומס על הזיכרון
אם המעקב מראה דפוס של שן מסור בשימוש בזיכרון, או ירידה בשימוש בזיכרון שקשורה לפריסות, יכול להיות שדליפת זיכרון היא הגורם לבעיות בביצועים. דליפת זיכרון עלולה גם לגרום ל-garbage collection תכוף, מה שמוביל לזמן אחזור גבוה יותר. אם לא הצלחתם לאתר את הבעיה בקוד, נסו להקצות מופעים גדולים יותר עם יותר זיכרון.
דליפת משאבים
אם מופע של האפליקציה מציג עלייה בחביון שקשורה לגיל המופע, יכול להיות שיש דליפת משאבים שגורמת לבעיות בביצועים. החביון יורד אחרי שהפריסה מסתיימת. לדוגמה, מבנה נתונים שפועל לאט יותר לאורך זמן בגלל שימוש גבוה יותר במעבד, עלול לגרום לעומס עבודה שמוגבל על ידי המעבד לפעול לאט יותר.
אופטימיזציה של קוד
כדי להפחית את זמן האחזור ב-App Engine, כדאי לבצע אופטימיזציה של הקוד באמצעות השיטות הבאות:
עבודה במצב אופליין: אפשר להשתמש ב-Cloud Tasks כדי למנוע מבקשות של משתמשים לחסום את האפליקציה בזמן שהיא ממתינה לסיום העבודה, כמו שליחת אימייל.
קריאות אסינכרוניות ל-API: מוודאים שהקוד לא נחסם בהמתנה להשלמת קריאה ל-API.
קריאות מקובצות ל-API: הגרסה המקובצת של קריאות ל-API בדרך כלל מהירה יותר משליחת קריאות בנפרד.
ביטול הנרמול של מודלים של נתונים: כדי לצמצם את זמן האחזור של קריאות שמתבצעות לשכבת שמירת הנתונים, מבטלים את הנרמול של מודלים של נתונים.
יחסי תלות של אפליקציות
עליכם לעקוב אחרי יחסי התלות של האפליקציה כדי לזהות אם יש קורלציה בין קפיצות בזמן האחזור לבין כשל ביחסי התלות.
שינוי בעומס העבודה (workload) ועלייה בתנועה עשויים לגרום לעלייה בחביון של תלות.
תלות שלא ניתנת להרחבה
אם התלות של האפליקציה לא גדלה ככל שמספר המופעים של App Engine גדל, יכול להיות שהתלות תגרום לעומס יתר כשתנועת הגולשים תגדל. דוגמה לתלות שלא ניתנת להרחבה היא מסד נתונים של SQL. מספר גבוה יותר של מופעי אפליקציה מוביל למספר גבוה יותר של חיבורים למסד הנתונים, מה שעלול לגרום לכשל מדורג ולמנוע את הפעלת מסד הנתונים. כדי לפתור את הבעיה:
- פורסים גרסת ברירת מחדל חדשה שלא מתחברת למסד הנתונים.
- משביתים את גרסת ברירת המחדל הקודמת.
- פריסת גרסה חדשה שלא מוגדרת כברירת מחדל, שמתחברת למסד הנתונים.
- מעבירים את התנועה לגרסה החדשה בהדרגה.
כדי למנוע את הבעיה, כדאי לתכנן את האפליקציה כך שהיא תבטל בקשות לתלות באמצעות הגבלת קצב דינמית.
כשל בשכבת ה-Caching
כדי לזרז את הבקשות, כדאי להשתמש בכמה שכבות של שמירה במטמון, כמו שמירה במטמון בקצה הרשת, Memcache וזיכרון במופע. תקלה באחת משכבות השמירה במטמון האלה עלולה לגרום לעלייה פתאומית ב-Latency. לדוגמה, ניקוי של Memcache עשוי לגרום ליותר בקשות להישלח אל Datastore איטי יותר.