Rate Limiting e Throttling em Rust: Dominando os Fluxos de Dados

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

Quando Rust encontra sobrecarga: por que seu serviço "cai"?

\n\n

Imagine que você escreveu em Rust um serviço ideal para alta carga. Ele voa, usa todas as vantagens das abstrações de custo zero e do gerenciamento de memória. Mas eis o problema — chega um cliente "ganancioso" e começa a bombardear seu servidor com milhares de requisições por segundo. O que acontece? O banco de dados cai? A fila sufoca? Ou, pior ainda, você é banido pela API externa que você mesmo consome?

\n\n

Em Rust, como em qualquer outra linguagem, sem rate limiting (limitação de velocidade) e throttling (estrangulamento) não se vai a lugar nenhum. Isso não é apenas uma "boa prática" — é uma questão de sobrevivência da sua aplicação em produção. Mas Rust tem uma particularidade: adoramos fazer tudo de forma eficiente e do zero. No entanto, não será preciso reinventar a roda — temos crates (bibliotecas) poderosas e padrões elegantes.

\n\n

Neste artigo, vamos analisar como implementar corretamente a limitação de requisições em Rust, usando tanto algoritmos clássicos (Token Bucket) quanto abordagens assíncronas modernas. Você aprenderá como proteger sua API contra ataques DDoS, como não exceder os limites de serviços externos e como escrever seu próprio throttler, que será mais rápido do que em Go ou Python.

\n\n

Rate Limiting vs Throttling: qual a diferença?

\n\n

Antes de mergulhar no código, vamos esclarecer de uma vez por todas os termos. Frequentemente são confundidos, mas a diferença é crítica.

\n\n
    \n
  • Rate Limiting — é uma política de segurança. Você diz: "O cliente X pode fazer no máximo 100 requisições por minuto". Se o limite for excedido — retorna 429 Too Many Requests. Isso protege seu backend.
  • \n
  • Throttling — é um mecanismo de controle de velocidade. Você decide a velocidade com que processa as requisições para não sobrecarregar a CPU, I/O ou o banco de dados. O cliente pode enviar 1000 requisições, mas você as processará a 10 por segundo, colocando as demais em fila.
  • \n
\n\n

Em Rust, ambas as abordagens podem ser implementadas com as mesmas ferramentas, mas com lógicas diferentes. Vamos abordar ambas.

\n\n

Algoritmos: Token Bucket e Leaky Bucket

\n\n

Os algoritmos mais populares para rate limiting são Token Bucket e Leaky Bucket. São simples como uma botija, mas incrivelmente eficientes.

\n\n

Token Bucket (Balde de Tokens)

\n

Imagine um balde no qual caem N tokens a cada segundo. Quando chega uma requisição, ela retira um token. Se o balde estiver vazio — a requisição é rejeitada. Rust é ideal para implementar este algoritmo graças às operações atômicas.

\n\n

Leaky Bucket (Balde Furado)

\n

Aqui, o balde tem um furo no fundo, por onde vaza uma quantidade fixa de requisições por segundo. As requisições entram no balde por cima. Se o balde transbordar — as requisições excedentes são descartadas. Este algoritmo é melhor para suavizar picos de carga.

\n\n

Em Rust, não vamos escrever esses algoritmos manualmente (embora seja instrutivo). Em vez disso, usaremos o crate governor — o padrão ouro de rate limiting no ecossistema Rust.

\n\n

Prática: Instalando o Governor

\n\n

O crate governor é uma implementação rápida, assíncrona e thread-safe do Token Bucket. Ele suporta modos síncrono e assíncrono, funcionando com tokio e async-std.

\n\n

Adicione ao Cargo.toml:

\n\n
[dependencies]\ngovernor = "0.6"\ntokio = { version = "1", features = ["full"] }\n
\n\n

Agora vamos escrever um rate limiter simples para um servidor HTTP baseado em hyper ou axum. Para simplificar, usaremos axum.

\n\n
use axum::{\n    extract::Request,\n    http::StatusCode,\n    middleware::{self, Next},\n    response::Response,\n    routing::get,\n    Router,\n};\nuse governor::{DefaultDirectRateLimiter, Quota, RateLimiter};\n                

Blogs

Book Recommendations