Rate Limiting в Rust: библиотеки для ограничения частоты запросов

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Rate Limiting в Rust: эффективное управление нагрузкой

Rate limiting (ограничение частоты запросов) — ключевой механизм защиты и оптимизации веб-сервисов, API и сетевых приложений. В экосистеме Rust существует несколько зрелых библиотек, реализующих различные алгоритмы: от классического токен-бакета до современных адаптивных методов. В этой статье мы разберём три основные библиотеки: governor, leaky-bucket и ratelimit, с примерами кода и рекомендациями по выбору.

1. Библиотека governor — золотой стандарт

governor — самая популярная и гибкая библиотека для rate limiting. Она реализует алгоритм Generic Cell Rate Algorithm (GCRA), который обеспечивает точное соблюдение лимитов с минимальной задержкой. Поддерживает синхронный и асинхронный режимы, middleware для Actix-web, Axum и Rocket.

Базовый пример с governor

use governor::{DefaultKeyedRateLimiter, Quota, RateLimiter};
use std::num::NonZeroU32;
use std::time::Duration;

fn main() {
    // Разрешаем 5 запросов в секунду
    let quota = Quota::per_second(NonZeroU32::new(5).unwrap());
    let limiter = RateLimiter::direct(quota);

    for i in 0..10 {
        match limiter.check() {
            Ok(_) => println!("Запрос {} разрешён", i),
            Err(_) => println!("Запрос {} отклонён (rate limit)", i),
        }
        std::thread::sleep(Duration::from_millis(100));
    }
}

Асинхронный вариант с ожиданием

use governor::{Quota, RateLimiter};
use std::num::NonZeroU32;
use tokio::time::{sleep, Duration};

#[tokio::main]
async fn main() {
    let limiter = RateLimiter::direct(Quota::per_second(
        NonZeroU32::new(2).unwrap(),
    ));

    for i in 0..5 {
        limiter.until_ready().await;
        println!("Обработан запрос {}", i);
        sleep(Duration::from_millis(300)).await;
    }
}

Ключевые возможности governor:

  • Поддержка ключевых лимитов (per-IP, per-user) через KeyedRateLimiter
  • Интеграция с tower middleware для HTTP-серверов
  • Настраиваемые стратегии: ожидание, отклонение, адаптивное замедление
  • Минимальное потребление памяти (один атомарный счётчик на лимитер)

2. Библиотека leaky-bucket — простота и надёжность

leaky-bucket реализует классический алгоритм «дырявого ведра». Он идеален для сглаживания пиковых нагрузок, когда нужно гарантировать равномерный поток запросов. Библиотека легковесна и не требует внешних зависимостей.

Пример с leaky-bucket

use leaky_bucket::RateLimiter;
use std::time::Duration;

#[tokio::main]
async fn main() {
    let limiter = RateLimiter::builder()
        .initial(10)        // начальный запас токенов
        .interval(Duration::from_secs(1))  // интервал пополнения
        .refill(5)          // сколько токенов добавлять за интервал
        .max(20)            // максимальное количество токенов
        .build();

    for i in 0..15 {
        limiter.acquire_one().await;
        println!("Запрос {} выполнен", i);
    }
}

Особенности leaky-bucket:

  • Поддержка асинхронного и блокирующего API
  • Возможность настройки «burst»-режима (кратковременные всплески)
  • Автоматическое освобождение токенов при простое

3. Библиотека ratelimit — минималистичный подход

ratelimit — самая простая библиотека, реализующая скользящее окно с фиксированными интервалами. Подходит для простых сценариев, где не нужна высокая точность.

Пример с ratelimit

use ratelimit::Ratelimiter;
use std::time::Duration;

fn main() {
    let mut limiter = Ratelimiter::builder(10, Duration::from_secs(1))
        .build()
        .unwrap();

    for i in 0..20 {
        if limiter.try_wait() {
            println!("Запрос {} разрешён", i);
        } else {
            println!("Запрос {} отклонён", i);
        }
        std::thread::sleep(Duration::from_millis(50));
    }
}

Когда выбирать ratelimit:

  • Прототипирование и MVP
  • Сценарии с низкой точностью (

Рекомендаций