תארו לעצמכם שאתם מריצים מבצע והבקאנד שלכם קורס תחת מבול של בקשות. בעומס שיא של 10,000 בקשות בשנייה, הגבלת קצב בתוך האפליקציה נכשלת בסנכרון בין השירותים — כל מיקרוסרוויס מחזיק מונה משלו, ופרץ גורם לחריגות מגבלה של 200%. הגבלת קצב מרכזית דרך API Gateway היא נקודת הבקרה היחידה שבה מדיניות מוחלת על כל התעבורה ללא שינוי בלוגיקה העסקית. ביצענו ביקורת ללקוח פינטק: לאחר יישום הגבלת קצב של Kong, שגיאות 429 ירדו ב-90%, ועומס הבקאנד ב-70%.
למה API Gateway במקום הגבלת קצב בתוך האפליקציה?
פתרון בתוך האפליקציה דורש שינויים בכל שירות, כפילות קוד ותיאום. Gateway הוא שכבה אחת שבה מדיניות מוחלת באופן אחיד. אין צורך לגעת בלוגיקה העסקית — רק להגדיר פלאגין. בנוסף, ניטור ולוגים מאוחדים, ויכולת לשנות מגבלות תוך כדי תנועה ללא פריסות.
השוואת גישות:
| מאפיין | API Gateway | בתוך האפליקציה | Middleware |
|---|---|---|---|
| נקודת מדיניות אחת | כן | לא | חלקי |
| שינוי ללא פריסה | כן | לא | כן |
| עומס על שירותים | מינימלי | בינוני | מינימלי |
| מורכבות תצורה | נמוכה | גבוהה | בינונית |
איזה אלגוריתם לבחור?
קיימים מספר אלגוריתמים, והבחירה תלויה בפרופיל העומס. Token Bucket (בשימוש Kong) מאפשר פרצים עד למגבלה הניתנת להגדרה, בעוד Leaky Bucket (זמין ב-APISIX) מחליק את התעבורה. Fixed Window פשוט אך יש לו אפקטי קצה; Sliding Window מציע דיוק גבוה.
| אלגוריתם | התנהגות | פרץ | דיוק | יישום |
|---|---|---|---|---|
| Token Bucket | דלי אסימונים מתמלא | כן | גבוה | רוב ה-API Gateways (פרץ ניתן להגדרה) |
| Leaky Bucket | דליפה בקצב קבוע | לא | גבוה | עומס צפוי, הגנה מפני חניקה |
| Fixed Window | מונה על חלון קבוע | לא | נמוך | תרחישים פשוטים, אך אפקט קצה של חלון |
| Sliding Window | חלון נע עם משקלים | כן | גבוה | דיוק קריטי, בדיקות A/B |
תצורה ב-Gateways ספציפיים
תצורה ב-Kong
Kong תומך במגבלות מרובות רמות: גלובלי, לכל שירות, לכל צרכן. משתמש ב-Redis לסנכרון. דוגמה דרך Admin API:
# Глобальный лимит (все сервисы) — 1000 запросов в минуту
curl -X POST http://localhost:8001/plugins \
-d "name=rate-limiting" \
-d "config.minute=1000" \
-d "config.hour=20000" \
-d "config.policy=redis" \
-d "config.redis_host=redis" \
-d "config.limit_by=ip"
# Лимит на уровне сервиса payments-api — 10 rps
curl -X POST http://localhost:8001/services/payments-api/plugins \
-d "name=rate-limiting" \
-d "config.second=10" \
-d "config.minute=200" \
-d "config.limit_by=consumer"
# Лимит для consumer free-tier — 60 запросов в минуту
curl -X POST http://localhost:8001/consumers/free-tier/plugins \
-d "name=rate-limiting" \
-d "config.minute=60" \
-d "config.hour=500"כותרות התגובה מכילות מגבלה וזמן איפוס. תיעוד רשמי: Kong Rate Limiting.
תצורה ב-APISIX
APISIX מספק שלושה פלאגינים: # Глобальный лимит (все сервисы) — 1000 запросов в минуту curl -X POST http://localhost:8001/plugins \ -d "name=rate-limiting" \ -d "config.minute=1000" \ -d "config.hour=20000" \ -d "config.policy=redis" \ -d "config.redis_host=redis" \ -d "config.limit_by=ip" # Лимит на уровне сервиса payments-api — 10 rps curl -X POST http://localhost:8001/services/payments-api/plugins \ -d "name=rate-limiting" \ -d "config.second=10" \ -d "config.minute=200" \ -d "config.limit_by=consumer" # Лимит для consumer free-tier — 60 запросов в минуту curl -X POST http://localhost:8001/consumers/free-tier/plugins \ -d "name=rate-limiting" \ -d "config.minute=60" \ -d "config.hour=500" (מונה), limit-count (דלי דולף), limit-req (חיבורים במקביל). דוגמה דרך Admin API:
{
"plugins": {
"limit-count": {
"count": 100,
"time_window": 60,
"rejected_code": 429,
"rejected_msg": "Too many requests",
"key": "consumer_name",
"policy": "redis",
"redis_host": "redis",
"redis_port": 6379,
"redis_database": 0,
"show_limit_quota_header": true
},
"limit-req": {
"rate": 10,
"burst": 5,
"key": "remote_addr",
"rejected_code": 429
},
"limit-conn": {
"conn": 50,
"burst": 10,
"key": "remote_addr",
"rejected_code": 503
}
}
}limit-conn מיישם Leaky Bucket — בקשות מעבר לקצב נכנסות לתור פרץ, ואז 429. { "plugins": { "limit-count": { "count": 100, "time_window": 60, "rejected_code": 429, "rejected_msg": "Too many requests", "key": "consumer_name", "policy": "redis", "redis_host": "redis", "redis_port": 6379, "redis_database": 0, "show_limit_quota_header": true }, "limit-req": { "rate": 10, "burst": 5, "key": "remote_addr", "rejected_code": 429 }, "limit-conn": { "conn": 50, "burst": 10, "key": "remote_addr", "rejected_code": 503 } } } מגביל חיבורים במקביל. הפלאגין limit-req של APISIX מספק בקרת פרץ טובה פי 2 מגישות Fixed Window.
תצורה ב-AWS API Gateway
AWS משתמש ב-Usage Plans עם הגבלת קצב ומכסה. דוגמת Terraform לארבע רמות:
resource "aws_api_gateway_usage_plan" "tiers" {
for_each = {
free = {
rate = 10
burst = 5
quota = 1000
period = "DAY"
}
basic = {
rate = 50
burst = 25
quota = 10000
period = "DAY"
}
pro = {
rate = 200
burst = 100
quota = 100000
period = "DAY"
}
enterprise = {
rate = 1000
burst = 500
quota = 0
period = "DAY"
}
}
name = "plan-${each.key}"
api_stages {
api_id = aws_api_gateway_rest_api.main.id
stage = "prod"
}
throttle_settings {
rate_limit = each.value.rate
burst_limit = each.value.burst
}
dynamic "quota_settings" {
for_each = each.value.quota > 0 ? [1] : []
content {
limit = each.value.quota
period = each.value.period
}
}
} הגבלת קצב דינמית לפי מאפייני עסק
מגבלות קצב לא תמיד תלויות רק ב-IP או במפתח API. לעיתים קרובות נדרשת לוגיקה: מנוי משתמש, סוג משאב, שעה ביום. דוגמה לפלאגין Kong מותאם אישית שמביא מגבלות משירות חיוב:
local function get_rate_limit(consumer_id)
local cache_key = "rate:" .. consumer_id
local cached = kong.cache:get(cache_key)
if cached then
return cached
end
-- Запрос к billing service
local client = httpc.new()
local res = client:request_uri("http://billing-service/limits/" .. consumer_id)
local limits = cjson.decode(res.body)
kong.cache:set(cache_key, limits, 300) -- кэш 5 минут
return limits
end
local limits = get_rate_limit(consumer_id)
-- limits = { minute: 1000, hour: 10000 } טעויות נפוצות וכיצד להימנע מהן
- פרץ לא מוגדר: אפילו עליות לגיטימיות נדחות. הגדירו פרץ של 50-100% מהקצב.
- אין רשימת היתרים לשירותים פנימיים: ניטור נכשל. השתמשו בפלאגין
limit-reqעם טווחי רשת. - שימוש ב-Fixed Window ללא התחשבות בקצה החלון: העומס בקצוות החלון מוכפל. השתמשו ב-Sliding Window או Leaky Bucket.
- לא מגדירים כותרת Retry-After: לקוחות לא יודעים מתי לנסות שוב. כללו תמיד
limit-connבתגובות 429. - Redis ללא שכפול: אם Redis נופל, המגבלות מתאפסות. השתמשו ב-Redis cluster או הגדירו רפליקה.
יישום ותמחור
- ביקורת של ארכיטקטורת ה-API הנוכחית ובחירת Gateway אופטימלי.
- עיצוב מדיניות: גלובלי, לכל שירות, לכל משתמש.
- הקמת Redis לסנכרון (אם נדרש).
- אינטגרציה עם ניטור (Prometheus, Grafana) להמחשת מגבלות.
- תיעוד של תוכנית הגבלת הקצב לצוות הפיתוח.
- הכשרת מהנדסים (סדנה של 2-3 שעות).
- התחייבות ל-SLA של 99.9% במהלך התפעול.
הגבלת קצב בסיסית רב-רמות (לפי IP, צרכן, שירות) עם Redis אורכת 2 עד 5 ימי עבודה בהתאם למורכבות האינטגרציה. הגדרה בסיסית מתחילה ב-$500, כולל סנכרון Redis ומדיניות ברירת מחדל. מגבלות דינמיות מותאמות למשתמש וניטור מותאם אישית נעים בין $2,000 ל-$5,000. אנו מחשבים עלות מדויקת לאחר ביקורת הארכיטקטורה שלכם. עם ניסיון של 5+ שנים ולמעלה מ-50 פרויקטי API Gateway שהושלמו, אנו מבטיחים פתרון אמין.
צרו קשר לייעוץ — נבחר את אסטרטגיית הגבלת הבקשות האופטימלית לעומס שלכם. קבלו הגנה לבקאנד החל מ-$500.
הערה: אלגוריתם Sliding Window מספק את הדיוק הגבוה ביותר עבור APIs קריטיים.







