חלוקת התנועה

מזהה אזור

REGION_ID הוא קוד מקוצר ש-Google מקצה על סמך האזור שבוחרים כשיוצרים את האפליקציה. הקוד לא תואם למדינה או למחוז, למרות שחלק ממזהי האזורים עשויים להיראות דומים לקודים נפוצים של מדינות ומחוזות. באפליקציות שנוצרו אחרי פברואר 2020, REGION_ID.r נכלל בכתובות URL של App Engine. באפליקציות קיימות שנוצרו לפני התאריך הזה, מזהה האזור הוא אופציונלי בכתובת ה-URL.

מידע נוסף על מזהי אזורים

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

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

  • https://PROJECT_ID.REGION_ID.r.appspot.com – מפזר את התנועה בין גרסאות של שירות default.
  • https://SERVICE_ID-dot-PROJECT_ID.REGION_ID.r.appspot.com – מפזר את התנועה בין גרסאות של שירות [SERVICE_ID].

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

לפני שמתחילים

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

איך נמנעים מבעיות שקשורות לשמירה במטמון

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

לדוגמה, נניח שאתם מפצלים את התנועה בין שתי גרסאות, A ו-B, ומשאב חיצוני מסוים שניתן לשמירה במטמון השתנה בין הגרסאות, למשל קובץ CSS. נניח שעכשיו לקוח שולח בקשה והתשובה מכילה הפניה חיצונית לקובץ שנשמר במטמון. מטמון ה-HTTP המקומי יאחזר את הקובץ אם הוא נמצא במטמון, בלי קשר לגרסת הקובץ שנשמרה במטמון ולגרסת האפליקציה ששלחה את התגובה. יכול להיות שהמשאב שנשמר במטמון לא תואם לנתונים שנשלחו בתגובה.

כדי למנוע בעיות שקשורות לשמירת נתונים במטמון:

  • למשאבים דינמיים, צריך להגדיר את הכותרות Cache-Control ו-Expires. הכותרות האלה מציינות לשרתי proxy שהמשאב הוא דינמי. מומלץ להגדיר את שתי הכותרות, כי לא כל שרתי ה-Proxy תומכים בכותרת Cache-Control של HTTP/1.1 כמו שצריך.

    אם רוצים לקבל מידע נוסף על שמירה במטמון באופן כללי, אפשר לעיין בשדות הכותרת ב-RFC של HTTP/1.1 ובסקירה הכללית על שמירה במטמון ב-HTTP במאמר בנושא Web Fundamentals (היסודות של בניית אתרים).

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

אפשר גם להגדיר באפליקציה את הכותרת Vary: Cookie כדי שהייחודיות של משאב תחושב על ידי שילוב של קובצי ה-Cookie וכתובת ה-URL של הבקשה. עם זאת, הגישה הזו מגדילה את העומס על שרתי המטמון. יש 1,000 ערכים אפשריים של GOOGAPPUID, ולכן 1,000 רשומות אפשריות לכל כתובת URL של האפליקציה. בהתאם לעומס על השרתים הפרוקסי בין המשתמשים לבין האפליקציה, יכול להיות שהאפליקציה תציג תוצאה ששמורה במטמון בתדירות נמוכה יותר. בנוסף, במשך 24 שעות אחרי שמוסיפים קבוצה חדשה של משתמשים לגרסה, יכול להיות שהמשתמשים האלה עדיין יראו משאבים ששמורים במטמון. עם זאת, שימוש ב-Vary: Cookie יכול להקל על שינוי השם של משאבים סטטיים שמשתנים בין גרסאות.

הטכניקה Vary: Cookie לא פועלת בכל הנסיבות. באופן כללי, אם האפליקציה שלכם משתמשת בקובצי Cookie למטרות אחרות, אתם צריכים לקחת בחשבון את ההשפעה של זה על העומס בשרתי proxy. אם ל-codeninja היה קובץ Cookie משלו עם 100 ערכים אפשריים, אז מרחב כל הערכים האפשריים במטמון יהיה מספר גדול מאוד (‎100 * 1,000 = 100,000). במקרה הגרוע ביותר, יש קובץ Cookie ייחודי לכל משתמש. שתי דוגמאות נפוצות לכך הן Google Analytics‏ (__utma) ו-SiteCatalyst‏ (s_vi). במקרים האלה, כל משתמש מקבל עותק ייחודי, מה שמפחית באופן משמעותי את ביצועי המטמון ויכול גם להגדיל את מספר השעות של מופע לחיוב שהאפליקציה צורכת.

פיצול התנועה בין כמה גרסאות

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

המסוף

כדי לפצל את התנועה במסוף Google Cloud , עוברים לדף Versions:

כניסה לדף Versions

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

gcloud

אחרי שמתקינים את Google Cloud CLI, מריצים את הפקודה הבאה כדי לפצל את התנועה בין כמה גרסאות, לדוגמה:

gcloud app services set-traffic [MY_SERVICE] --splits [MY_VERSION1]=[VERSION1_WEIGHT],[MY_VERSION2]=[VERSION2_WEIGHT] --split-by [IP_OR_COOKIE]

פרטים ואפשרויות נוספות זמינים במקור המידע gcloud app services set-traffic.

API

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

פיצול של כתובות IP

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

יש כמה מגבלות משמעותיות לפיצול כתובות IP:

  • כתובות ה-IP של השולחים הן יציבות למדי, אבל לא קבועות. יכול להיות שכתובת ה-IP של משתמשים שמתחברים מטלפונים סלולריים תשתנה במהלך סשן אחד. באופן דומה, משתמש במחשב נייד עשוי לעבור מהבית לבית קפה כדי לעבוד, ולכן כתובת ה-IP שלו תשתנה. כתוצאה מכך, יכול להיות שחוויית השימוש של המשתמש באפליקציה תהיה לא עקבית כי כתובת ה-IP שלו משתנה.
  • כתובות IP מוקצות לגרסאות באופן עצמאי, ולכן חלוקת התנועה שיתקבל יהיה שונה במידה מסוימת ממה שציינתם. עם זאת, ככל שהאפליקציה מקבלת יותר תנועה, כך הפיצול בפועל מתקרב ליעד שהגדרתם. לדוגמה, אם תבקשו להעביר 5% מהתנועה לגרסה חלופית, האחוז הראשוני של התנועה לגרסה עשוי להיות בין 3% ל-7%, אבל בסופו של דבר הממוצע יהיה קרוב יותר ל-5% שהגדרתם.
  • אם אתם צריכים לשלוח בקשות פנימיות בין אפליקציות, כדאי להשתמש בפיצול קובצי Cookie. בקשות שנשלחות בין אפליקציות שפועלות בתשתית הענן של Google מגיעות ממספר קטן של כתובות IP, שסביר להניח שכולן מוקצות לאותה גרסה. לכן, יכול להיות שכל הבקשות הפנימיות יתנהגו באופן דומה לבקשות שנשלחות מכתובת IP אחת, כלומר כל הבקשות האלה מנותבות לאותה גרסה. כתוצאה מכך, הבקשות הפנימיות לא מכבדות את האחוזים שהגדרתם לפי פיצול התנועה שמבוסס על כתובות IP. לדוגמה, אם הגדרתם גרסה שתקבל 1% מכל התנועה לאפליקציה, וכתובות תשתית הענן של Google הוקצו במקרה לגרסה הזו, התוצאה בפועל עשויה להיות גבוהה בהרבה מ-1%, כי כל הבקשות הפנימיות תמיד מנותבות לגרסה שהוקצתה. בקשות שנשלחות לאפליקציה שלכם מחוץ לתשתית הענן של Google יפעלו כצפוי, כי הן מגיעות מכתובות IP שונות.

אם בוחרים לפצל את התנועה לאפליקציה לפי קובצי Cookie, האפליקציה מחפשת בכותרת בקשת ה-HTTP קובץ Cookie בשם GOOGAPPUID, שמכיל ערך בין 0 ל-999:

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

אם התגובה לא מכילה את קובץ ה-Cookie ‏GOOGAPPUID, האפליקציה מוסיפה קודם את קובץ ה-Cookie ‏GOOGAPPUID עם ערך אקראי מוסווה בין 0 ל-999 לפני שהיא נשלחת.

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

לדוגמה, אם יש לכם 3 גרסאות:

  • גרסה א' עם 10% מהתנועה
  • ‫Version B with 60% of Traffic
  • Version C with 30% of Traffic

‫App Engine יוצר 1,000 רסיסים, ולכל גרסה מוקצה מספר רסיסים שמתאים לאחוז חלוקת התנועה שלה. מהדוגמה הזו אפשר לראות שלגרסה א' יש 100 רסיסים, לגרסה ב' יש 600 רסיסים ולגרסה ג' יש 300 רסיסים.

מערכת App Engine משתמשת בערך של קובץ ה-Cookie‏ GOOGAPPUID כדי לקבוע לאיזה שבר בקשה משויכת, ומנתבת את הבקשה לגרסה המתאימה. רמת הדיוק של ניתוב התנועה עשויה להתקרב ל-0.1% מהפיצול המיועד. יש כמה מגבלות לפיצול קובצי Cookie:

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

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

  • אין דרך לקבוע איזו גרסה מטפלת בערך מסוים בקובץ ה-Cookie ‏GOOGAPPUID. עם זאת, אותו גרסה מטפלת בבקשות עם אותו ערך בקובץ ה-Cookie‏ GOOGAPPUID.

השבתה של חלוקת התנועה

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