במקרים רבים, חביון גבוה באפליקציה מוביל בסופו של דבר לשגיאות שרת 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 מתרחבים בהתאם לניצול ה-CPU. יכול להיות שהאפליקציה שלך תהיה מוגבלת על ידי קלט/פלט במהלך אירוע שגורם לעומס יתר על המופעים עם מספר גבוה של בקשות, כי לא מתבצעת התאמה אוטומטית של גודל המשאבים שמבוססת על CPU.
מומלץ להשוות את הביצועים עם הגדרות ברירת המחדל של שינוי הגודל, ואז להריץ השוואה חדשה אחרי כל שינוי בהגדרות האלה.
פריסות
עלייה בזמן האחזור זמן קצר אחרי פריסה מצביעה על כך שלא הגדלתם את הקיבולת בצורה מספקת לפני העברת התנועה. יכול להיות שבמופעים חדשים יותר המטמון המקומי לא חומם, והם פועלים לאט יותר ממופעים ישנים יותר.
כדי למנוע קפיצות בערכי השהייה, אל תפרסו שירות App Engine באמצעות אותו שם גרסה כמו גרסה קיימת של השירות. אם משתמשים בשם של גרסה קיימת, לא ניתן להעביר את התנועה לגרסה החדשה בהדרגה. יכול להיות שהבקשות יהיו איטיות יותר כי App Engine מפעיל מחדש כל מופע תוך פרק זמן קצר. אם רוצים לחזור לגרסה הקודמת, צריך גם לפרוס מחדש.
מופע של אפליקציה
בקטע הזה מתוארות האסטרטגיות הנפוצות שאפשר להחיל על מופעי האפליקציה ועל קוד המקור כדי לשפר את הביצועים ולהפחית את זמן האחזור.
קוד אפליקציה
יכול להיות שיהיה קשה לאתר באגים בבעיות בקוד האפליקציה, במיוחד אם הן מתרחשות לסירוגין או שלא ניתן לשחזר אותן.
כדי לפתור את הבעיות:
כדי לאבחן את הבעיות, מומלץ להטמיע באפליקציה רישום ביומן, מעקב ויומני מעקב. אפשר גם להשתמש ב-Cloud Profiler.
נסו לשחזר את הבעיה בסביבת פיתוח מקומית, שאולי תאפשר לכם להפעיל כלי ניפוי באגים ספציפיים לשפה, שלא ניתן להפעיל ב-App Engine.
אפשר להיכנס עם SSH למופע ולאסוף dump של השרשור כדי לראות את המצב הנוכחי של האפליקציה. משחזרים את הבעיה בבדיקת עומס או על ידי הפעלת האפליקציה באופן מקומי. אפשר להגדיל את גודל המופע כדי לראות אם הבעיה תיפתר. לדוגמה, הגדלת ה-RAM עשויה לפתור בעיות באפליקציות שמתעכבות בגלל garbage collection.
כדי להבין טוב יותר איך האפליקציה נכשלת ואילו צווארי בקבוק מתרחשים, כדאי לבצע בדיקת עומס באפליקציה עד שהיא נכשלת. מגדירים מספר מקסימלי של מופעים, ואז מגדילים בהדרגה את העומס עד שהאפליקציה נכשלת.
אם הבעיה של זמן האחזור קשורה לפריסה של גרסה חדשה של קוד האפליקציה, כדאי לבצע החזרה לגרסה קודמת כדי לבדוק אם הגרסה החדשה גרמה לתקרית. עם זאת, אם אתם מבצעים פריסה באופן רציף, קשה לקבוע אם הפריסה גרמה לאירוע על סמך שעת ההתחלה.
יכול להיות שהאפליקציה שלכם מאחסנת הגדרות תצורה ב-Datastore או במקום אחר. יוצרים ציר זמן של שינויים בהגדרות כדי לבדוק אם יש התאמה בין השינויים לבין תחילת העלייה בחביון.
שינוי בעומס העבודה
שינוי בעומס העבודה (workload) עלול לגרום לזמן אחזור ארוך יותר. חלק ממדדי הניטור שמצביעים על שינויים בעומס העבודה כוללים את qps, השימוש ב-API והחביון. כדאי גם לבדוק אם יש שינויים בגודל הבקשה והתשובה.
כשלים בבדיקת התקינות
מאזן העומסים בסביבה הגמישה של App Engine מפסיק להפנות בקשות למופעים שנכשלים בבדיקות התקינות. הפעולה הזו עלולה להגדיל את העומס על מופעים אחרים, וכתוצאה מכך לגרום לכשל מדורג. ביומני Nginx מוצגים מופעים שנכשלו בבדיקות התקינות. כדי להבין למה המופע לא תקין, צריך לנתח את היומנים ואת נתוני המעקב, או להגדיר בדיקות תקינות שיהיו פחות רגישות לכשלים זמניים. יש השהיה קצרה לפני שמאזן העומסים מפסיק להפנות תנועה למופע לא תקין. העיכוב הזה עלול לגרום לעלייה חדה במספר השגיאות אם מאזן העומסים לא יכול לנסות שוב לשלוח בקשות.
עומס על הזיכרון
אם המעקב מראה דפוס של שן מסור בשימוש בזיכרון, או ירידה בשימוש בזיכרון שקשורה לפריסות, יכול להיות שדליפת זיכרון היא הגורם לבעיות בביצועים. דליפת זיכרון עלולה גם לגרום ל-garbage collection תכוף, מה שמוביל לזמן אחזור גבוה יותר. אם לא הצלחתם לאתר את הבעיה בקוד, נסו להקצות מופעים גדולים יותר עם יותר זיכרון.
דליפת משאבים
אם מופע של האפליקציה מציג עלייה בחביון שקשורה לגיל המופע, יכול להיות שיש דליפת משאבים שגורמת לבעיות בביצועים. החביון יורד אחרי שהפריסה מסתיימת. לדוגמה, מבנה נתונים שפועל לאט יותר לאורך זמן בגלל שימוש גבוה יותר במעבד, עלול לגרום לעומס עבודה שמוגבל על ידי המעבד לפעול לאט יותר.
אופטימיזציה של קוד
כדי להפחית את זמן האחזור ב-App Engine, כדאי לבצע אופטימיזציה של הקוד באמצעות השיטות הבאות:
עבודה במצב אופליין: אפשר להשתמש ב-Cloud Tasks כדי למנוע מבקשות של משתמשים לחסום את האפליקציה בזמן שהיא ממתינה לסיום העבודה, כמו שליחת אימייל.
קריאות אסינכרוניות ל-API: מוודאים שהקוד לא נחסם בהמתנה להשלמת קריאה ל-API.
קריאות מקובצות ל-API: הגרסה המקובצת של קריאות ל-API בדרך כלל מהירה יותר משליחת קריאות נפרדות.
ביטול הנרמול של מודלים של נתונים: כדי לצמצם את זמן האחזור של קריאות שמתבצעות לשכבת שמירת הנתונים, מבטלים את הנרמול של מודלים של נתונים.
יחסי תלות בין אפליקציות
עליכם לעקוב אחרי יחסי התלות של האפליקציה כדי לזהות אם יש קורלציה בין קפיצות בזמן האחזור לבין כשל ביחסי התלות.
שינוי בעומס העבודה (workload) ועלייה בתנועה עשויים לגרום לעלייה בחביון של תלות.
תלות שלא ניתנת להרחבה
אם התלות של האפליקציה לא גדלה ככל שמספר המופעים של App Engine גדל, יכול להיות שהתלות תגרום לעומס יתר כשתנועת הגולשים תגדל. דוגמה לתלות שלא ניתנת להרחבה היא מסד נתונים של SQL. מספר גבוה יותר של מופעי אפליקציה מוביל למספר גבוה יותר של חיבורים למסד הנתונים, מה שעלול לגרום לכשל מדורג ולמנוע את הפעלת מסד הנתונים. כדי לפתור את הבעיה:
- פורסים גרסת ברירת מחדל חדשה שלא מתחברת למסד הנתונים.
- משביתים את גרסת ברירת המחדל הקודמת.
- פריסת גרסה חדשה שלא מוגדרת כברירת מחדל, שמתחברת למסד הנתונים.
- מעבירים את התנועה לגרסה החדשה בהדרגה.
כדי למנוע את הבעיה, כדאי לתכנן את האפליקציה כך שהיא תבטל בקשות לתלות באמצעות הגבלת קצב דינמית.
כשל בשכבת ה-Caching
כדי לזרז את הבקשות, כדאי להשתמש בכמה שכבות של שמירה במטמון, כמו שמירה במטמון בקצה הרשת, Memcache וזיכרון במופע. תקלה באחת משכבות השמירה במטמון האלה עלולה לגרום לעלייה פתאומית ב-Latency. לדוגמה, ניקוי של Memcache עשוי לגרום ליותר בקשות להישלח אל Datastore איטי יותר.