עודכן לפני חודש
ה-API שלך הוא משאב משותף. כל בקשה צורכת מחזורי מעבד, חיבורי מסד נתונים, זיכרון, רוחב פס. ללא מגבלות, לקוח אחד — זדוני או סתם כתוב ברשלנות — יכול לצרוך הכל, ולא להשאיר דבר לאחרים.
הגבלת קצב פותרת את זה. היא השומר בכניסה, שמחליט כמה בקשות כל לקוח רשאי לשלוח ומה קורה כשהוא חורג מהמכסה שלו.
הבעיה שהגבלת קצב פותרת
דמיינו מפתח שכותב סקריפט לשליפת נתונים מה-API שלכם. הוא שוכח להוסיף השהיה בין בקשות. הסקריפט רץ בלולאה צפופה ושולח אלפי בקשות בשנייה. תוך רגעים, מאגר חיבורי מסד הנתונים שלכם מתרוקן. שרתי ה-API שלכם מוצפים. כל משתמש אחר ב-API שלכם נתקל בשגיאות ובפסקי זמן.
זו לא זדוניות — זו באג. אבל ההשפעה אינה נבדלת מהתקפת מניעת שירות.
הגבלת קצב עוצרת את זה לפני שהוא מתחיל. מאה הבקשות הראשונות עוברות. בקשה מספר 101 נדחית עם הודעה ברורה: "האטו. נסו שוב בעוד 60 שניות."
הסקריפט הפגום נכשל במהירות. המפתח מתקן את הבאג. המשתמשים האחרים שלכם לא שמים לב לכלום.
מדוע כל API ציבורי זקוק לזה
הגנה על תשתית היא הסיבה הברורה. שחקן רע אחד — או סקריפט גרוע — לא אמור לפגוע בשירות שלכם.
הוגנות היא הסיבה העמוקה יותר. ל-API שלכם יש קיבולת מוגבלת. אם משתמש אחד יכול לצרוך משאבים ללא הגבלה, הוא לוקח מכולם. הגבלת קצב מבטיחה שהעוגה מתחלקת בצורה שוויונית.
שליטה בעלויות חשובה כאשר ה-API שלכם קורא לשירותים חיצוניים, מריץ שאילתות יקרות, או מפעיל פונקציות ענן. ללא מגבלות, לקוח שיצא מכלל שליטה עלול לצבור חשבון עצום לפני שמישהו שם לב.
מודל עסקי צומח באופן טבעי. מסלול חינמי: 100 בקשות לשעה. מסלול בתשלום: 10,000 בקשות לשעה. ארגוני: בואו נדבר. הגבלת קצב היא לא רק הגנה — היא מוצר.
האלגוריתמים
לגישה הפשוטה ביותר יש פגם ברור. הפגם הוביל לגישות טובות יותר. הבנת ההתפתחות הזו תעזור לכם לבחור את הגישה הנכונה.
חלון קבוע
אפשרו N בקשות לכל חלון זמן. כאשר החלון מתאפס, המונה חוזר לאפס.
100 בקשות לדקה. ב-10:00:00, המונה הוא 0. עד 10:00:45, המשתמש שלח 95 בקשות. הוא שולח עוד 5. הוא הגיע למגבלה. הוא ממתין עד 10:01:00, והמונה מתאפס.
פשוט. קל להבנה. קל למימוש.
הנה הפגם: לקוח שולח 100 בקשות ב-10:00:59. החלון מתאפס ב-10:01:00. הוא שולח עוד 100 בקשות ב-10:01:01. זה 200 בקשות ב-2 שניות — למרות מגבלת "100 לדקה".
בעיית הגבול. המגבלה שלכם אינה באמת מה שחשבתם.
חלון גולש
במקום גבולות קבועים, מסתכלים אחורה בדיוק חלון אחד מהרגע הנוכחי.
ב-10:00:45, סופרים את כל הבקשות מ-09:59:45 עד 10:00:45. אם פחות מ-100, הבקשה עוברת.
אין בעיית גבול. "100 לדקה" אכן אומר 100 בכל תקופה של 60 שניות.
המחיר: צריך לאחסן חותמות זמן לכל בקשה. הזיכרון מצטבר.
קירוב חכם: שומרים מונים לחלון הנוכחי והקודם, ואז מחשבים ממוצע משוקלל לפי המיקום בתוך החלון הנוכחי. פחות זיכרון, דיוק כמעט זהה.
דלי אסימונים
דמיינו דלי המכיל אסימונים. לדלי יש קיבולת מרבית והוא מתמלא בקצב קבוע. כל בקשה צורכת אסימון אחד. אם הדלי ריק, הבקשה נדחית.
קיבולת: 100 אסימונים. קצב מילוי: 10 אסימונים לשנייה.
משתמש שולח 50 בקשות במהירות, צורך 50 אסימונים. הוא ממתין 5 שניות. הדלי מתמלא ב-50 אסימונים. הוא יכול לפרוץ שוב.
זהו האלגוריתם שרוב ה-API-ים בסביבת הייצור משתמשים בו. הוא מאפשר רצפים של בקשות אינטנסיביות (עד קיבולת הדלי) תוך אכיפת קצב ממוצע לאורך זמן. תנועה מפורצת היא נורמלית. דלי האסימונים מתמודד איתה בצורה טבעית.
דלי דולף
בקשות נכנסות לתור. התור מתרוקן בקצב קבוע. אם התור מתמלא, בקשות חדשות נדחות.
קצב הפלט חלק לחלוטין, ללא קשר לכמה מפורצת הכניסה. אך בקשות ממתינות בתור ומוסיפות זמן תגובה. עבור רוב ה-API-ים, זמן ההמתנה הנוסף אינו שווה את החלקות.
מה מוגבל
ניתן להחיל מגבלות בהיקפים שונים, לרוב בשילוב:
לפי מפתח API: לכל יישום יש מגבלה משלו. הבאג של יישום אחד לא משפיע על אחרים.
לפי משתמש: כאשר מספר יישומים ניגשים ל-API שלכם בשם משתמשים שונים, כל משתמש מקבל מגבלה משלו.
לפי כתובת IP: מגן מפני התקפות אפילו לפני שהאימות מתרחש.
לפי נקודת קצה: פעולות יקרות מקבלות מגבלות הדוקות יותר מאשר פעולות זולות. חיפוש מורכב עשוי לאפשר 10 בקשות לדקה בעוד חיפוש פשוט מאפשר 1,000.
גלובלי: תקרה על עומס המערכת הכולל, ללא תלות במגבלות הבודדות.
תצורה טיפוסית: 1,000 בקשות למפתח API לשעה, בצירוף 10 בקשות לשנייה לכתובת IP. הגנה כפולה.
לספר ללקוחות מה קורה
לקוחות צריכים לדעת את המגבלות, כמה השתמשו, ומתי המגבלות מתאפסות. כותרות HTTP הן הסטנדרט:
כאשר עוברים את המגבלה, מחזירים קוד סטטוס 429 (Too Many Requests) עם כותרת Retry-After:
הודעות שגיאה טובות הן תכונה חשובה. המפתח שמאבחן בשעה 2 לפנות בוקר יודה לכם.
מימוש
עבור שרת יחיד, מונים בזיכרון עובדים מצוין. מהיר ופשוט. אבל כאשר יש מספר שרתים, לכל אחד יש מונים משלו — לקוח יכול לחרוג מהמגבלות על ידי שליחת בקשות לשרתים שונים.
לפריסות מרובות-שרתים, Redis הוא התשובה הסטנדרטית. כל השרתים חולקים את אותם המונים. פעולות הגדלה אטומיות מונעות תנאי מרוץ. Redis מהיר מספיק כדי שבדיקת הגבלת הקצב מוסיפה עיכוב זניח.
שערי API (Kong, AWS API Gateway, Cloudflare) מטפלים בהגבלת קצב לפני שהבקשות מגיעות ליישום שלכם. זה יעיל — בקשות שנדחו אינן נוגעות בשרתים שלכם — ומרכז את הלוגיקה במקום אחד.
לקבל את המספרים נכון
מחמיר מדי: משתמשים לגיטימיים פוגעים במגבלות במהלך שימוש רגיל. תסכול. כרטיסי תמיכה. נטישה.
מקל מדי: המגבלות לא מגינות על דבר. לקוח שמתנהג ברשלנות עדיין יכול לגרום לבעיות.
התחילו בניתוח שימוש בפועל. כיצד נראה המשתמש באחוזון ה-95? הגדירו מגבלות שנמצאות בנוחות מעל השימוש הרגיל אך מתחת לנקודה שבה משתמש יחיד יכול לגרום לבעיות.
לאחר מכן — עקבו. שיעורים גבוהים של שגיאות 429 ממשתמשים רבים מרמזים שהמגבלות נוקשות מדי. שיעורים גבוהים ממשתמש אחד מרמזים שעליו לתקן את הקוד שלו — או לשדרג את התוכנית.
דפוסים מתקדמים
מגבלות אדפטיביות מתכווננות לפי עומס המערכת. כאשר המערכת פועלת תקין, אפשר להיות נדיבים. כאשר היא עמוסה, מהדקים. זה ממקסם תפוקה תוך שמירה על ההגנה.
מגבלות מבוססות עלות גובות כמויות שונות עבור פעולות שונות. חיפוש פשוט עולה נקודה אחת. איחוד מורכב עולה 10. משתמשים מקבלים תקציב נקודות ולא מספר בקשות. זה הוגן יותר — למה שבקשה קלה תיחשב אותו דבר כמו בקשה יקרה?
מגבלות מבוססות מוניטין מעניקות למשתמשים ותיקים יותר מרחב פעולה מאשר לחשבונות חדשים. אמון נרכש.
הגבלת קצב לעומת מיתון
הגבלת קצב דוחה בקשות שחורגות מהמגבלות. הלקוח מקבל 429 ומחליט מה לעשות.
מיתון מכניס בקשות לתור ומעבד אותן בקצב המותר. הלקוח ממתין.
רוב ה-API-ים משתמשים בהגבלת קצב. מיתון עלול לגרום לפסקי זמן וקשה יותר ללקוחות לתכנן סביבו. עדיף להיכשל מהר עם הודעה ברורה מאשר להיתקע בהמתנה ללא הגבלת זמן.
שאלות נפוצות על הגבלת קצב ב-API
למה לא פשוט להוסיף שרתים במקום להגביל קצב?
הוספת שרתים מטפלת בצמיחת עומס לגיטימית. הגבלת קצב מטפלת בניצול לרעה, בבאגים ובהתקפות. בוטנט או סקריפט מוגדר-שגוי יכולים לייצר עומס מהר יותר מכל מנגנון הרחבה אוטומטית. הגבלת קצב עוצרת את הדימום מיידית, בזמן שאתם מבינים מה קורה.
כיצד לבחור בין חלון קבוע לדלי אסימונים?
דלי אסימונים הוא כמעט תמיד הבחירה הטובה יותר עבור API בסביבת ייצור. חלון קבוע פשוט יותר למימוש ולהסבר, אך בעיית הגבול אומרת שהמגבלות שאתם מכריזים עליהן אינן באמת מה שמתקיים בפועל. דלי אסימונים מתמודד עם תנועה מפורצת בצורה טבעית תוך אכיפת קצבים ממוצעים אמיתיים.
האם כדאי להגביל בקשות מאומתות ולא-מאומתות בצורה שונה?
כן. נקודות קצה לא-מאומתות חשופות לכל האינטרנט — כל אחד יכול להגיע אליהן. שמרו שם על מגבלות הדוקות (אולי 10–50 בקשות לשעה לכתובת IP). בקשות מאומתות מגיעות ממשתמשים שהוכיחו אמינות כלשהי — שם המגבלות יכולות להיות גבוהות בהרבה.
מה צריך לקרות לאחר הפרות חוזרות של מגבלת קצב?
תגובה מדורגת הגיונית. הפרה ראשונה: 429 עם זמן המתנה לניסיון חוזר. הפרות חוזרות בתקופה קצרה: זמני המתנה ארוכים יותר. ניצול לרעה מתמשך: חסימה זמנית. זה מטפל הן בטעויות כנות — שנעצרות מהר — והן בהתנהגות זדונית, שנסגרת.
האם דף זה היה מועיל?