Реалізація Throttling для API веб-застосунку

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.
Розробка та обслуговування будь-яких видів сайтів:
Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Реалізація Throttling для API веб-застосунку
Середня
від 1 робочого дня до 3 робочих днів
Часті питання
Наші компетенції:
Етапи розробки
Останні роботи
  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Throttling API для веб-застосунку

Throttling — управління швидкістю обробки запитів на рівні сервера, на відміну від rate limiting, який обмежує клієнта. Throttling сповільнює або ставить в чергу вхідні запитів, щоб захистити бекенд від перегрузу. Різниця принципова: rate limit говорить «ти зробив занадто багато запитів», throttling говорить «ми обробляємо стільки, скільки можемо».

Throttling vs Rate Limiting

Аспект Rate Limiting Throttling
Суб'єкт Клієнт (IP, user_id) Сервер (CPU, черга)
Дія при перевищенні 429, запит відхилено Запит затримано або поставлено в чергу
Мета Захист від зловживань Захист ресурсів бекенду
Відповідь клієнту Негайна 429 Затримка або 503

На практиці обидва механізми застосовуються разом.

Throttling важких операцій

Деякі операції — експорт звіту, обробка файлу, розсилання email — не мають виконуватися паралельно в необмеженій кількості:

// 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 },
});

Adaptive throttling

Адаптивний throttling знижує ліміти при зростанні latency або помилок:

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;
  }
}

Google використовує аналогічний механізм у своїх сервісах («Client-Side Throttling» з SRE book).

Circuit Breaker

Throttling для вихідних запитів до зовнішніх API — Circuit Breaker паттерн:

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 (якщо успішно).

Throttling вхідних webhook'ів

Партнери можуть надсилати тисячи webhook'ів одночасно (наприклад, при масовому оновленні статусів замовлень). Правильний паттерн — прийняти швидко (202), поставити в чергу:

// 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 паралельних
],

Throttling в Nginx upstream

upstream backend {
    server app1:3000;
    server app2:3000;

    # Обмеження одночасних з'єднань до upstream
    keepalive 32;
}

# queue — буферизація при перегрузі
location /api/ {
    proxy_pass http://backend;
    proxy_connect_timeout 1s;
    proxy_read_timeout 30s;

    # Якщо backend не відповідає швидко — 503 замість зависання
    proxy_next_upstream error timeout http_503;
    proxy_next_upstream_tries 2;
}

Моніторинг throttling

Метрики для дашборду:

// Prometheus counters
throttleRejected.inc({ reason: 'queue_full', endpoint: '/api/export' });
throttleDelayed.observe({ endpoint: '/api/export' }, delayMs);
queueDepth.set({ queue: 'reports' }, await queue.count());

Алерт: queue depth > 1000 протягом 5 хвилин → Scale up workers або сповіщення дежурному.

Строки

BullMQ з concurrency + rateLimit, circuit breaker для зовнішніх API, webhook-черга: 3–5 днів. З adaptive throttling, Prometheus-метриками, Grafana-дашбордом і алертами: 1–2 тижні.