Rate Limiting: Защита системы

Даже если у тебя идеально настроена балансировка, один злонамеренный (или просто забагованный) клиент может отправить миллион запросов в секунду и положить всю систему. Для защиты API используются ограничители.

  1. Requests Rate Limiter (Ограничитель частоты): Стандартное ограничение по времени (например, 100 запросов в минуту). Использует алгоритмы по типу: Token Bucket, Fixed Window.
  2. Concurrent Requests Limiter (Ограничитель параллельности): Ограничивает количество активных запросов в моменте. Защищает тяжелые API от исчерпания пула потоков. Здесь не нужны сложные алгоритмы с токенами, используются классические семафоры или атомарные счетчики (пришел запрос: +1, ушел: -1).
Алгоритмы: Нет серебряной пули

Почему алгоритмов так много? Потому что мы всегда балансируем между точностью, эффективностью по памяти и простотой распределения в кластере.

Давай разберем несколько классических алгоритмов для Requests Rate Limiter.

1. Token Bucket (Маркерная корзина)

Представь ведро, в которое сервер раз в секунду кладет монетку (токен). У ведра есть максимальная вместимость (например, 10 токенов). Когда приходит запрос, он забирает один токен и выполняется. Нет токена — запрос отклоняется (HTTP 429 Too Many Requests).

  • Плюсы: Идеально обрабатывает кратковременные спайки (bursts). Если клиент долго молчал, токены накопились, и он может отправить сразу 10 запросов одновременно. Очень мало потребляет памяти.
  • Минусы: Сложнее синхронизировать токены в распределенной системе (когда API Gateway запущен в 5 разных контейнерах).
2. Fixed Window (Фиксированное окно)

Время делится на жесткие интервалы (например, с 12:00:00 до 12:01:00). На каждое окно выделен лимит. Превысил лимит внутри окна — жди следующей минуты.

  • Плюсы: Элементарная реализация (просто инкрементим счетчик в Redis по ключу user_id:minute).
  • Минусы (Уязвимость границ): Злоумышленник может обмануть систему, отправив весь трафик на стыке двух окон, и сервер получит двойную нагрузку за пару секунд.
Визуализация уязвимости (Проблема границ)

Представь, что лимит: 100 запросов в минуту. Клиент ждет конца минуты и делает следующее:

Шикарная статья, где глубоко разбираются все эти алгоритмы (включая продвинутый Sliding Window Log) с примерами кода.