יחידה 8 / 11

מגבלות מהירות וניהול שגיאות עמיד

רווחים:

  • יכול לפרש מגבלות מהירות (RPM/ITPM/OTPM) ושגיאות 429
  • מיישם גיבוי אקספוננציאלי וניסיון חוזר עם ניסיון חוזר לאחר
  • מסווג נכון ומטפל בקודי שגיאה נפוצים של HTTP (400/401/429/500/529)

בסביבת ייצור, אף API לא מגיב בצורה מושלמת כל הזמן. לפעמים אתה שולח בקשות מהר מדי ופוגע במגבלה; לפעמים השרת תפוס זמנית; לפעמים הבקשה שלך שגויה מההתחלה. מה שמבדיל בין אינטגרציה מוצקה לבין ניסיון חובב הוא שהיא מטפלת במצבים אלו באופן חיזוי ואוטומטי. ביחידה זו תלמדו על מגבלות קצב (RPM/ITPM/OTPM), שגיאה 429, ניסיון חוזר עם השבתה אקספוננציאלית וסיווג נכון של קודי שגיאה נפוצים של HTTP. המטרה: לבנות זרימה כל כך חזקה שמשתמש לעולם לא יבחין בה.

מהן מגבלות מהירות?

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

  • RPM (Requests Per Minute): מספר בקשות לדקה.
  • ITPM (אסימוני קלט לדקה): אסימון קלט שניתן לעבד בדקה.
  • OTPM (אסימוני פלט לדקה): אסימון פלט שניתן להפיק לדקה.

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

טיפ: אתה יכול לצפות כאשר אתה מתקרב לגבול מכותרות התגובה. רוב הספקים מדווחים על המכסה שנותרה שלך עם כותרות כמו x-ratelimit-remaining-*. ניטור ערכים אלו והפחתת התנועה מלפנים היא הדרך הבוגרת ביותר למנוע את הבעיה מבלי לקבל 429.

429 ותיקון אקספוננציאלי

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

# ניסוי גיבוי אקספוננציאלי 1 → 429 → המתן 1 שניות ניסיון 2 → 429 → המתן 2 שניות ניסיון 3 → 429 → המתן 4 שניות ניסיון 4 → 429 → המתן 8 שניות (+ "ריצוד" אקראי קטן... לוותר ולדווח לכל היותר לאחר N ניסויים

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

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

סיווג קודי שגיאה של HTTP

לא כל טעות זהה. הבחנה קריטית: האם ניתן לנסות זאת שוב או שזו בעיה של בקשה/זהות?

קוד

משמעות

האם ניתן לנסות שוב?

תגובה נכונה

400

בקשה לא חוקית (שגיאת פורמט/פרמטר)

לא

תקן את הבקשה; אל תשלח אותו שוב

401

שגיאת אימות (מפתח לא חוקי/חסר)

לא

תקן מפתח/כותרת

403

ללא הרשאה (ללא גישה לדגם/תכונה)

לא

בדוק הרשאות/היקף

404

לא נמצא (מזהה דגם/נקודת קצה שגויים)

לא

זיהוי דגם/כתובת נכונים

429

חרגת מהמהירות המותרת

כן

נסיגה + ניסיון חוזר-אחרי

500

שגיאת שרת

כן

נסה שוב עם נסיגה

529

השרת עמוס יתר על המידה

כן

נסה שוב עם נסיגה

כלל הזהב: 429, 500 ו-529 זמניים; זה נוסה שוב עם נסיגה. 400, 401, 403, 404 הם נושאי בקשה/זהות; לנסות שוב לא יפתור את זה, וזה מבזבז מאמץ. הקוד שלך חייב להבחין בין שתי הקבוצות הללו.

צעד אחר צעד: שיחה עמידה

  1. הגש את הבקשה. אם מצליח, המשך.
  2. סיווג את קוד השגיאה. האם ניתן לנסות שוב?
  3. אם ניתן לנסות: עקוב אחר ניסיון חוזר לאחר, החל גיבוי אקספוננציאלי + ריצוד, נסה מספר מוגבל של פעמים (לדוגמה, מקסימום 5).
  4. אם לא ניסית: תקן (פורמט/מפתח) והפסק; אל תחזור על אותה בקשה שגויה בלופ.
  5. תשקול לוותר. אם עדיין לא הצליח לאחר n ניסיונות, הצג הודעה מנומסת למשתמש ורשם את האירוע (יחידת מעקב 11).

# קריאה חזקה pseudo-codedene = 0repeat: response = request_at() if response.success: החזרת תגובה if response.code ב-[429, 500, 529] ונסה < 5: wait = retry_after ?? (2^try sec + ריצוד) sleep(wait); נסה += 1; git שוב אם response.code ב-[400, 401, 403, 404]: save_error(response); החזר "יש לתקן את הבקשה" החזר "שגיאה קבועה, נסה מאוחר יותר"

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

הנחיה חלשה / הנחיה חזקה (כאן: עיצוב הודעת שגיאה)

# WEAK (מציג שגיאה גולמית למשתמש)"שגיאה 429: rate_limit_error"

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

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

שלושה מיני מארזים

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

מקרה 2 - מנסה 400 בלולאה. אינטגרציה קיבלה 404 עקב מזהה דגם לא חוקי, אך התייחסה לכל השגיאות כ"חולפות" וניסתה שוב בלולאה אינסופית; היומן התנפח ונוצר עומס מיותר. הם הוסיפו סיווג שגיאה: 404 נחשב קבוע, הלולאה נעצרת ומזהה הדגם תוקן. לקח: אל תנסה כל טעות שוב.

מקרה 3 - ניהול הגבול מלפנים. עבודת העשרת נתונים פעלה ללא הרף במגבלה של 429. הם עקבו אחר הכותרת X-ratelimit-נותרת והצמצמו את התנועה בהתאם למכסה. אז הם שמרו על קצב יציב ממש מתחת לגבול, מבלי לקחת 429 כלים; העבודה נעשתה בצורה צפויה ומהירה יותר.

טעויות נפוצות

  • הגדלת המהירות ב-429: מחמירה את המצב; עוברים לנסיגה.
  • ניסיון חוזר של כל שגיאה: 400/401/404 הוא קבוע; לנסות שוב זה בזבוז.
  • שימוש בהמתנה קבועה: יוצר התנגשות; השתמש אקספוננציאלי + ריצוד.
  • התעלמות מ'ניסיון חוזר-אחרי': הכי מדויק לעמוד בזמן שצוין על ידי הספק.
  • חשיפת השגיאה הגולמית למשתמש: מנער אמון, יוצר נקודות תורפה; מסווג פנימה.
  • ניסיונות חוזרים ללא הגבלה: הגדר גבול עליון (למשל 5 ניסיונות חוזרים); ואז לוותר בחן.

עמוק יותר: תור, מקביל ומפסקי חשמל

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

תור: אתה שם בקשות בתור כדי לשלוח אותן בקצב מבוקר ולא באופן מיידי. תור מחליק פרצי תנועה פתאומיים: גם אם יגיעו 1,000 בקשות בבת אחת, התור ישחרר אותן בקצב מתחת לגבול. בדרך זו אתה מונע 429, אז אתה לא צריך לדאוג לתקן את זה.

מגבלת במקביל: אתה מגביל כמה בקשות "באוויר" בו-זמנית. בקשות מקבילות בלתי מוגבלות ממלאות במהירות את מגבלות ה-RPM וה-TPM. תקרת בו זמנית סבירה (למשל לא יותר מ-10 בקשות במקביל) גם שומרת על מגבלות וגם הופכת את המערכת לניתנת לחיזוי.

מפסק מעגל: אם הספק ממשיך להחזיר 500/529, במקום לנסות בעקשנות כל בקשה, אתה "שובר את המעגל" לזמן מה ונכשל במהירות את הבקשה מבלי לשלוח אותה. לאחר המתנה, אתה מדליק שוב את המעגל ומנסה. דפוס זה מונע מהמערכת שלך לקרוס במקרה של כשל זמני בספק.

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

לסיכום

429 חוזר כאשר חריגה ממגבלת המהירות (RPM/ITPM/OTPM); זוהי שגיאה זמנית והיא תבוצע מחדש באמצעות ניסיון חוזר לאחר וגיבוי אקספוננציאלי + ריצוד. גם 500 ו-529 זמניים; 400/401/403/404 היא בעיית בקשה/זהות ולא ניתן לפתור אותה על ידי ניסיון שוב. זרימה חזקה מפרידה שגיאות לשתי הקבוצות הללו, מנסה מספר מצומצם של פעמים, מנטרת את הגבול מלפנים ומציגה הודעות רגועות למשתמש.

משימת יישום

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

רשימת בדיקה

  • [ ] אני יכול להסביר את מגבלות RPM/ITPM/OTPM ו-429.
  • [ ] אני יכול ליישם את ההיגיון של נסיגה אקספוננציאלית + ריצוד + ניסיון חוזר-אחרי.
  • [ ] אני יכול לסווג קודי שגיאה כניתנים לניסיון חוזר/קבוע.
  • [ ] אני יודע שאסור לנו לנסות כל טעות.
  • [ ] במקום שגיאה גולמית, אני יכול להראות למשתמש הודעה רגועה ומכוונת לפעולה.