מגבלות קצב

ב-Google Ads API, הגבלת הקצב של יצירת הבקשות מתבצעת לפי שאילתות לשנייה (QPS) גם במזהי לקוחות וגם בפרויקטים בענן ב-Google Cloud, באופן נפרד. בנוסף למגבלות על מספר הבקשות לדקה (שמודדות את תדירות הקריאות ל-API), ב-Google Ads API יש גם מגבלות על מספר הפעולות לדקה (שמודדות את המספר הכולל של פעולות ה-API בכל הבקשות). ב-Google Ads API נעשה שימוש באלגוריתם token bucket כדי למדוד את הבקשות ולקבוע מגבלת QPS מתאימה, כך שהמגבלה המדויקת משתנה בהתאם לעומס הכולל על השרת בכל זמן נתון.

המטרה של הגבלת קצב הבקשות היא למנוע ממשתמש אחד לשבש את השירות למשתמשים אחרים, על ידי הצפת שרתי Google Ads API בכמות גדולה של בקשות (בכוונה או בטעות).

בקשות שחורגות ממגבלות הקצב נדחות ומוצגת השגיאה: RESOURCE_TEMPORARILY_EXHAUSTED.

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

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

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

השהיה מעריכית לפני ניסיון חוזר (exponential backoff)

כשהאפליקציה מקבלת שגיאת RESOURCE_TEMPORARILY_EXHAUSTED, צריך להשתמש במדיניות של השהיה מעריכית לפני ניסיון חוזר (exponential backoff) עם רעידות אקראיות לפני שמנסים שוב לשלוח את הבקשה שנכשלה. השהיה מעריכית לפני ניסיון חוזר מגדילה בהדרגה את זמן ההמתנה בין ניסיונות חוזרים (לדוגמה, המתנה של 2 שניות, אחר כך 4 שניות, אחר כך 8 שניות, בתוספת עיכוב אקראי קטן), וכך מאפשרת לעומס השרת ולמכסות להתאושש, ומונעת שיאים של ניסיונות חוזרים מסונכרנים במופעי לקוח.

הגבלת משימות בו-זמניות

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

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

בנוסף, אפשר לשקול ויסות של QPS מצד הלקוח (ראו ויסות והגבלת קצב של יצירת בקשות).

בקשות Batch

כדאי לשקול שליחת כמה פעולות בבקשה אחת. ההגדרה הזו רלוונטית בעיקר לשיחות ב-Mutate בשירותים שונים. לדוגמה, אם אתם מעדכנים את הסטטוס של כמה מופעים של AdGroupAd, אתם יכולים להפעיל את MutateAdGroupAds פעם אחת ולהעביר כמה operations במקום להפעיל את MutateAdGroupAds פעם אחת לכל AdGroupAd. דוגמאות נוספות מפורטות בהנחיות לפעולות באצווה.

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

ויסות נתונים והגבלת קצב של יצירת בקשות

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

אפשר לעיין ב-Guava RateLimiter או להטמיע אלגוריתם token bucket משלכם לסביבה מקובצת. לדוגמה, אפשר לנהל אסימונים במאגר נתונים מבוזר בזיכרון עם זמן אחזור נמוך, כמו Redis או Memcached, שבו כל לקוח מקבל אסימון ומשתמש בו לפני עיבוד הבקשה. אם האסימונים נגמרים, הלקוח ממתין עד שהקבוצה הבאה של האסימונים מתחדשת.

הוספה לתור

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

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

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