הטמעת חסימת קצב (API Throttling) עבור יישומי Web
תארו לעצמכם: השרת האחורי שלכם מטפל ב-1000 בקשות בשנייה, אבל לפתע שירות שותף מתחיל לשלוח 10,000 webhooks בדקה. ללא חסימת קצב, השרת קורס, שגיאות 500 מציפות, ומשתמשים עוזבים. בפרויקט מסחר אלקטרוני אחד, הטמעת חסימת קצב הניבה חיסכון משמעותי על ידי הפחתת עומס וביטול הצורך במופעים נוספים. חסימת קצב היא הדרך היחידה לשמור על שליטה: היא לא דוחה בקשות אלא מאטה אותן או מעמידה אותן בתור, ונותנת לשרת האחורי זמן לנשום.
חסימת קצב מנהלת את קצב עיבוד הבקשות ברמת השרת, בניגוד להגבלת קצב (rate limiting), שמגבילה את הלקוח. ההבדל הוא מהותי: הגבלת קצב אומרת "ביצעת יותר מדי בקשות," בעוד חסימת קצב אומרת "אנחנו מעבדים כמה שאנחנו יכולים." שתי הגישות פועלות יחד — כך אנחנו מגנים גם על לקוחות וגם על התשתית. הגנה על APIs מעומס יתר היא המטרה העיקרית של חסימת קצב. בפרויקט אחד, הטמעת חסימת קצב הפחיתה שגיאות 500 מ-15% ל-0.5% וחתכה את זמן ההשהיה p95 מ-1200 ms ל-200 ms.
למה חסימת קצב חיונית עבור APIs בעומס גבוה
ללא חסימת קצב, עומסי שיא גורמים לכשלים מדורגים: השרת האחורי העמוס מפסיק להגיב, nginx חורג מהזמן המוקצב, לקוחות מנסים שוב — והעומס גדל. חסימת קצב מחליקה את הקפיצות, ומאפשרת לשרת לפעול ביציבות. בפרויקטים שלנו, הטמעת חסימת קצב הפחיתה את מספר שגיאות ה-500 ב-90% והקטינה את זמן ההשהיה p95 ב-40%.
חסימת קצב לעומת הגבלת קצב
| היבט | הגבלת קצב | חסימת קצב |
|---|---|---|
| נושא | לקוח (IP, user_id) | שרת (CPU, תור) |
| פעולה בחריגה | 429, בקשה נדחית | בקשה מתעכבת או נכנסת לתור |
| מטרה | הגנה מפני ניצול לרעה | הגנה על משאבי השרת האחורי |
| תגובת הלקוח | 429 מיידי | עיכוב או 503 |
בפועל, שני המנגנונים משמשים יחד. לדוגמה, במכירת בזק אצל קמעונאי, הגבלת קצב חוסמת לקוחות שחורגים מהמגבלה שלהם, בעוד חסימת קצב מעמידה בתור בקשות תקפות כדי למנוע קריסת השרת האחורי.
השוואת שיטות חסימת קצב אדפטיבית
| שיטה | אלגוריתם | מתי ליישם |
|---|---|---|
| קבועה | מגבלה קבועה (N בקשות/שנייה) | עומס יציב, תרחישים פשוטים |
| אדפטיבית | מגבלה דינמית לפי מדדים | עומסי שיא, תעבורה לא יציבה |
| Circuit Breaker | השבתה בשיעור שגיאות גבוה | הגנה מפני כשלים של שירותים חיצוניים |
חסימת קצב לפעולות כבדות
חלק מהפעולות — ייצוא דוחות, עיבוד קבצים, שליחת קמפיינים במייל — לא צריכות לרוץ במקביל ללא מגבלות. BullMQ עם מגביל קצב יעיל פי 10 מתור ידני עם setTimeout — אימת�ו זאת בבדיקות עומס.
// BullMQ — throttle через concurrency + rateLimit
const queue = new Queue('reports', { connection: redis });
const worker = new Worker('reports', processReport, {
connection: redis,
concurrency: 5, // максимум 5 параллельных задач
limiter: {
max: 10, // 10 задач
duration: 60_000, // за 60 секунд
},
});
// Добавление задачи с приоритетом
await queue.add('generate-csv', { userId, filters }, {
priority: user.plan === 'enterprise' ? 1 : 10,
attempts: 3,
backoff: {
type: 'exponential',
delay: 2000,
},
});
איך חסימת קצב אדפטיבית מונעת כשלים
חסימת קצב אדפטיבית מתאימה מגבלות באופן דינמי בתגובה למדדי השרת. כאשר זמן ההשהיה p95 חורג מ-500 ms או ששיעור השגיאות עולה, המגבלה יורדת; כשהמצב מתנרמל, היא עולה:
class AdaptiveThrottler {
private limit = 100;
private readonly minLimit = 10;
private readonly maxLimit = 100;
async check(): Promise<boolean> {
const metrics = await this.getMetrics();
// Снижаем лимит при высоком p95 latency
if (metrics.p95Latency > 500) {
this.limit = Math.max(this.minLimit, this.limit * 0.8);
} else if (metrics.p95Latency < 200 && metrics.errorRate < 0.01) {
this.limit = Math.min(this.maxLimit, this.limit * 1.1);
}
return this.counter.increment() <= this.limit;
}
}גוגל משתמשת במנגנון דומה בשירותיה (Client-Side Throttling מתוך SRE book).
Circuit Breaker עבור APIs חיצוניים
חסימת קצב לבקשות יוצאות משתמשת בתבנית Circuit Breaker. היא מונעת כשלים מדורגים אם שירות חיצוני אינו זמין. ספריית Opossum מממשת תבנית זו ב-Node.js:
import CircuitBreaker from 'opossum';
const options = {
timeout: 3000, // запрос > 3 секунд = fail
errorThresholdPercentage: 50, // 50% ошибок → open
resetTimeout: 30000, // через 30 сек пробуем снова (half-open)
volumeThreshold: 10, // минимум 10 запросов для подсчёта
};
const breaker = new CircuitBreaker(callExternalAPI, options);
breaker.on('open', () => logger.warn('Circuit breaker OPEN — external API unavailable'));
breaker.on('halfOpen', () => logger.info('Circuit breaker HALF-OPEN — testing'));
breaker.on('close', () => logger.info('Circuit breaker CLOSE — external API recovered'));
// Fallback при открытом circuit
breaker.fallback(() => ({ status: 'cached', data: getCachedData() }));מצבים: Closed (רגיל) → Open (יותר מדי שגיאות, בקשות חסומות) → Half-Open (בקשת בדיקה) → Closed (אם הצליחה).
חסימת קצב ל-Webhooks נכנסים
שותפים יכולים לשלוח אלפי webhooks בו-זמנית (לדוגמה, בעדכוני סטטוס הזמנות בכמות גדולה). התבנית הנכונה היא לקבל במהירות (202), ואז להעמיד בתור. להלן דוגמה ב-Laravel באמצעות Horizon:
// WebhookController.php — немедленный ответ
public function handle(Request $request) {
$payload = $request->all();
$signature = $request->header('X-Signature');
if (!$this->verifySignature($payload, $signature)) {
return response()->json(['error' => 'Invalid signature'], 401);
}
// Кладём в очередь с throttle
ProcessWebhook::dispatch($payload)
->onQueue('webhooks')
->delay(now()); // немедленно, но через очередь
return response()->json(['accepted' => true], 202);
}
// config/queue.php — лимит воркеров для очереди webhooks
// Horizon:
'webhooks' => [
'connection' => 'redis',
'queue' => ['webhooks'],
'balance' => 'auto',
'maxProcesses' => 10, // не более 10 параллельных
], דוגמה לתצורת חסימת קצב ב-Nginx
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
server {
location /api/ {
limit_req zone=api burst=20 nodelay;
}
}זה מגביל את קצב הבקשות ל-10 בשנייה עם פרץ של עד 20.
ניטור חסימת קצב
מדדים ללוח המחוונים: עומק התור, זמן השהיה p95, מספר בקשות שנדחו/עוכבו, שיעור שגיאות. אנו משתמשים ב-Prometheus לאיסוף וב-Grafana להדמיה. התראה: עומק תור > 1000 למשך 5 דקות → הגדל עובדים או עדכן את המהנדס התורן.
מה כלול בהטמעת חסימת קצב
- ביקורת צווארי בקבוק נוכחיים (איסוף מדדים, פרופילינג)
- תכנון תכנית חסימת קצב (תורים, circuit breaker, לוגיקה אדפטיבית)
- פיתוח ושילוב קוד (BullMQ, Opossum, כלים מותאמים)
- הגדרת ניטור והתראות (Prometheus + Grafana)
- תיעוד תפעולי ובדיקות עומס
- הבטחת פעילות יציבה תחת עומס, ניסיון של 10+ שנים
לוחות זמנים
הטמעה בסיסית (תור + circuit breaker) — 3–5 ימים. עם חסימת קצב אדפטיבית, מדדים ולוח מחוונים — 1–2 שבועות. העלות מחושבת באופן אישי — צרו קשר ונעריך את הפרויקט שלכם.
קבלו ייעוץ ממהנדס — ננתח את הארכיטקטורה שלכם ונבחר את הפתרון האופטימלי. הזמינו הטמעת חסימת קצב עם תוצאה מובטחת.







