Rate limiting em Rust: bibliotecas governor, leaky-bucket e middleware para servidores web

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

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 tokio ou async-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")), }}

Recommendations