חלוקת התנועה

מזהה אזור

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% מהתנועה
  • גרסה ב' עם 60% מהתנועה
  • גרסה C עם 30% מהתנועה

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

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

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

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

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

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

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