Rate limiting em Rust: visão geral de bibliotecas e ferramentas
Rate limiting (limitação de frequência de requisições) é um mecanismo criticamente importante para proteger serviços web contra sobrecargas, ataques DDoS e abusos. No ecossistema Rust, existem várias bibliotecas maduras para implementar rate limiting: desde algoritmos de baixo nível até middleware prontos para frameworks web populares. Neste artigo, vamos examinar três abordagens principais: governor (algoritmo GCRA), leaky-bucket (balde furado) e integração com Actix/Axum.
1. Biblioteca governor — algoritmo GCRA
governor é a biblioteca de rate limiting mais popular em Rust, baseada no Generic Cell Rate Algorithm (GCRA). Este algoritmo é usado em protocolos de rede e permite configurar de forma flexível tanto a carga de pico quanto a velocidade média.
Principais recursos:
- Suporte a múltiplas chaves (IP, User-Agent, chave de API)
- Burst configurável (pico de tráfego)
- Operação assíncrona via
tokioouasync-std - Segurança de thread sem bloqueios
Exemplo de configuração de limite de 100 requisições por minuto com burst de 20:
use governor::{DefaultKeyedRateLimiter, Quota, RateLimiter};use std::num::NonZeroU32;use std::time::Duration;
#[tokio::main]async fn main() { // Limite: 100 requisições por minuto, burst 20 let quota = Quota::with_period(Duration::from_secs(60)) .unwrap() .allow_burst(NonZeroU32::new(20).unwrap()); let limiter = DefaultKeyedRateLimiter::::new(quota); // Verificação para o usuário "user123" match limiter.check_key("user123") { Ok(_) => println!("Requisição permitida"), Err(_) => println!("Limite excedido, status 429"), }} 2. Biblioteca leaky-bucket — balde furado
O algoritmo do balde furado é implementado na biblioteca leaky-bucket. Ele modela um balde com água que é preenchido com requisições e vaza a uma velocidade constante. É adequado para suavizar picos de carga.
Características:
- Modelo simples: balde com capacidade de N requisições
- Taxa de vazamento — número de requisições por segundo
- Suporte a máximo de requisições pendentes
Exemplo com limite de 5 requisições por segundo e balde de 10:
use leaky_bucket::RateLimiter;use std::time::Duration;
#[tokio::main]async fn main() { let limiter = RateLimiter::builder() .initial(10) // quantidade inicial de tokens .max(10) // tamanho máximo do balde .interval(Duration::from_millis(200)) // recarga a cada 200 ms .build(); // Tentativa de obter um token if limiter.try_acquire().is_ok() { println!("Requisição processada"); } else { println!("Balde vazio, recusado"); }}3. Middleware para frameworks web
Middlewares prontos simplificam significativamente a integração de rate limiting em servidores web com Actix e 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")), }} Também na biblioteca
Symfony/Console para PHP: guia completo com exemplos
Geração Swagger/OpenAPI para JavaScript (Node.js) — ferramentas e bibliotecas
Programação Reativa em Swift: Combine e RxSwift para iOS/macOS
Rate Limiting em PHP: Limitação de Frequência de Requisições para Proteção do Site