← Назад к вопросам

Приведи пример троттлинга трафика

1.0 Junior🔥 142 комментариев
#Инструменты тестирования

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Пример реализации троттлинга трафика

Троттлинг трафика (throttling) — это механизм контроля скорости обработки запросов или передачи данных, который используется для защиты систем от перегрузки, обеспечения стабильности работы и соблюдения лимитов использования API. В отличие от рейт-лимитинга, который обычно ограничивает количество запросов за временной интервал, троттлинг часто фокусируется на ограничении скорости потока данных или частоты операций в реальном времени.

Ключевые сценарии применения

  • Защита backend-сервисов от DDoS-атак или неконтролируемого роста нагрузки
  • Обеспечение качества обслуживания (QoS) для разных категорий пользователей
  • Соблюдение лимитов внешних API (например, платёжных систем или социальных сетей)
  • Контроль пропускной способности при стриминге данных или файловых загрузках
  • Предотвращение исчерпания ресурсов базы данных или кэша

Практический пример: Throttling Middleware на Python (FastAPI)

Рассмотрим реализацию простого middleware для троттлинга на основе токенов в бакете (token bucket) — популярного алгоритма, который позволяет регулировать среднюю скорость запросов с возможностью кратковременных всплесков.

import time
from fastapi import FastAPI, Request, HTTPException
from collections import defaultdict
from threading import Lock

app = FastAPI()

class TokenBucketThrottler:
    def __init__(self, rate: float, capacity: int):
        """
        rate: количество токенов в секунду
        capacity: максимальный размер бакета
        """
        self.rate = rate
        self.capacity = capacity
        self.tokens = capacity
        self.last_update = time.time()
        self.lock = Lock()
        # Храним отдельные бакеты для разных пользователей
        self.user_buckets = defaultdict(lambda: {'tokens': capacity, 'last_update': time.time()})
    
    def is_allowed(self, user_id: str = "default") -> bool:
        """Проверяем, разрешён ли запрос для указанного пользователя"""
        with self.lock:
            bucket = self.user_buckets[user_id]
            now = time.time()
            time_passed = now - bucket['last_update']
            
            # Пополняем бакет токенами пропорционально прошедшему времени
            new_tokens = time_passed * self.rate
            bucket['tokens'] = min(self.capacity, bucket['tokens'] + new_tokens)
            bucket['last_update'] = now
            
            # Если есть хотя бы один токен — разрешаем запрос
            if bucket['tokens'] >= 1:
                bucket['tokens'] -= 1
                return True
            return False

# Создаём троттлер: 10 запросов в секунду с возможностью всплеска до 30
throttler = TokenBucketThrottler(rate=10, capacity=30)

@app.middleware("http")
async def throttle_middleware(request: Request, call_next):
    # Извлекаем идентификатор пользователя (в реальном приложении — из токена или IP)
    user_id = request.headers.get("X-User-ID", request.client.host)
    
    if not throttler.is_allowed(user_id):
        # Возвращаем 429 Too Many Requests при превышении лимита
        raise HTTPException(
            status_code=429,
            detail="Превышен лимит запросов. Попробуйте позже.",
            headers={"Retry-After": "1"}
        )
    
    response = await call_next(request)
    # Добавляем заголовки с информацией о лимитах
    response.headers["X-RateLimit-Policy"] = "10; burst=30"
    return response

@app.get("/api/data")
async def get_data():
    """Пример защищённого троттлингом эндпоинта"""
    return {"status": "success", "data": "Ваши важные данные"}

@app.get("/unlimited")
async def get_unlimited():
    """Эндпоинт без ограничений"""
    return {"status": "unlimited"}

Пример троттлинга на стороне клиента (JavaScript)

Троттлинг также применяется на клиентской стороне для ограничения частоты вызовов событий:

class Throttler {
    constructor(delayMs) {
        this.delayMs = delayMs;
        this.lastCall = 0;
        this.timeoutId = null;
    }

    // Функция throttle гарантирует, что переданная функция
    // будет вызываться не чаще, чем раз в delayMs миллисекунд
    throttle(func, ...args) {
        const now = Date.now();
        const timeSinceLastCall = now - this.lastCall;
        const remainingDelay = this.delayMs - timeSinceLastCall;

        if (remainingDelay <= 0) {
            // Достаточно времени прошло — вызываем сразу
            this.lastCall = now;
            func.apply(null, args);
        } else {
            // Устанавливаем отложенный вызов
            clearTimeout(this.timeoutId);
            this.timeoutId = setTimeout(() => {
                this.lastCall = Date.now();
                func.apply(null, args);
            }, remainingDelay);
        }
    }
}

// Пример использования
const searchThrottler = new Throttler(300); // Максимум 1 запрос в 300мс

async function performSearch(query) {
    console.log(`Поиск: ${query}`);
    // Здесь был бы реальный API-запрос
}

// Обработчик ввода в поле поиска
document.getElementById('search-input').addEventListener('input', (event) => {
    searchThrottler.throttle(performSearch, event.target.value);
});

Тестирование троттлинга в QA

При тестировании механизмов троттлинга важно проверять:

  • Корректность ограничений — соблюдаются ли заявленные лимиты
  • Справедливость распределения — не блокируются ли легитимные пользователи
  • Восстановление после блокировки — как система ведёт себя после периода ограничений
  • Граничные условия — поведение при одновременных запросах от множества клиентов
  • Заголовки ответа — наличие Retry-After, X-RateLimit-* и других информационных заголовков

Отличия от рейт-лимитинга

Важно понимать разницу между троттлингом и рейт-лимитингом:

  • Троттлинг — плавное ограничение скорости (например, 100 запросов/секунду)
  • Рейт-лимитинг — жёсткое ограничение количества (например, 1000 запросов в час)

На практике эти механизмы часто комбинируются для создания многоуровневой защиты API.

Реализация эффективного троттлинга требует учёта специфики приложения, паттернов нагрузки и бизнес-требований, но правильно настроенный механизм значительно повышает отказоустойчивость и предсказуемость системы.

Приведи пример троттлинга трафика | PrepBro