Rate limiting в Rust: библиотеки governor, leaky-bucket и middleware для веб-серверов

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

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

Начать курс

Rate limiting в Rust: обзор библиотек и инструментов

Rate limiting (ограничение частоты запросов) — критически важный механизм защиты веб-сервисов от перегрузок, DDoS-атак и злоупотреблений. В экосистеме Rust доступно несколько зрелых библиотек для реализации rate limiting: от низкоуровневых алгоритмов до готовых middleware для популярных веб-фреймворков. В этой статье рассмотрим три ключевых подхода: governor (алгоритм GCRA), leaky-bucket (дырявое ведро) и интеграцию с Actix/Axum.

1. Библиотека governor — алгоритм GCRA

governor — самая популярная библиотека rate limiting в Rust, основанная на Generic Cell Rate Algorithm (GCRA). Этот алгоритм используется в сетевых протоколах и позволяет гибко настраивать как пиковую нагрузку, так и среднюю скорость.

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

  • Поддержка нескольких ключей (IP, User-Agent, API-ключ)
  • Настраиваемый burst (всплеск трафика)
  • Асинхронная работа через tokio или async-std
  • Потокобезопасность без блокировок

Пример настройки лимита 100 запросов в минуту с burst 20:

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

#[tokio::main]
async fn main() {
    // Лимит: 100 запросов в минуту, burst 20
    let quota = Quota::with_period(Duration::from_secs(60))
        .unwrap()
        .allow_burst(NonZeroU32::new(20).unwrap());
    
    let limiter = DefaultKeyedRateLimiter::::new(quota);
    
    // Проверка для пользователя "user123"
    match limiter.check_key("user123") {
        Ok(_) => println!("Запрос разрешён"),
        Err(_) => println!("Лимит превышен, статус 429"),
    }
}

2. Библиотека leaky-bucket — дырявое ведро

Алгоритм дырявого ведра реализован в библиотеке leaky-bucket. Он моделирует ведро с водой, которое наполняется запросами и протекает с постоянной скоростью. Подходит для сглаживания пиковых нагрузок.

Особенности:

  • Простая модель: ведро ёмкостью N запросов
  • Скорость утечки — количество запросов в секунду
  • Поддержка максимума ожидающих запросов

Пример с лимитом 5 запросов в секунду и ведром на 10:

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

#[tokio::main]
async fn main() {
    let limiter = RateLimiter::builder()
        .initial(10)       // начальное количество токенов
        .max(10)           // максимальный размер ведра
        .interval(Duration::from_millis(200)) // пополнение каждые 200 мс
        .build();
    
    // Попытка получить токен
    if limiter.try_acquire().is_ok() {
        println!("Запрос обработан");
    } else {
        println!("Ведро пусто, отказ");
    }
}

3. Middleware для веб-фреймворков

Готовые middleware значительно упрощают интеграцию rate limiting в веб-серверы на Actix и Axum.

Actix + governor

use actix_web::{web, App, HttpServer, HttpRequest, HttpResponse, middleware::from_fn};
use governor::{DefaultKeyedRateLimiter, Quota};
use std::num::NonZeroU32;
use std::time::Duration;

async fn rate_limit_middleware(
    req: HttpRequest,
    limiter: web::Data<DefaultKeyedRateLimiter<String>>,
) -> Result<HttpResponse, actix_web::Error> {
    let client_ip = req.peer_addr()
        .map(|addr| addr.to_string())
        .unwrap_or_default();
    
    match limiter.check_key(&client_ip) {
        Ok(_) => Ok(HttpResponse::Ok().body("OK")),
        Err(_) => Ok(HttpResponse::TooManyRequests().body("Too Many Requests")),
    }
}

Axum + tower-governor

use axum::{Router, response::IntoResponse, routing::get};
use tower_governor::{governor::GovernorLayer, GovernorConfig};

#[tokio::main]
async fn main() {
    let config = GovernorConfig::default(); // 1000 req/min
    let app = Router::new()
        .route("/", get(|| async { "Hello, world!" }))
        .layer(GovernorLayer { config });
    
    axum::Server                    

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