Rate limiting em C++: bibliotecas e ferramentas para controle de requisições

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 C++: guia completo para limitação de requisições



Rate limiting (limitação de velocidade de requisições) é um mecanismo criticamente importante para proteger servidores, APIs e sistemas distribuídos contra sobrecargas, ataques DDoS e picos aleatórios de tráfego. Em C++, a implementação de rate limiting requer algoritmos eficientes e a escolha correta de bibliotecas. Neste artigo, abordaremos as principais abordagens, bibliotecas populares e forneceremos exemplos de código prontos.



O que é rate limiting e por que é necessário?

Rate limiting estabelece o número máximo de requisições que um cliente ou sistema pode executar em um determinado intervalo de tempo. Os principais objetivos são:

  • Proteção contra abusos e sobrecarga do servidor
  • Garantir a distribuição uniforme de recursos entre os usuários
  • Prevenção de ataques DDoS e ataques de força bruta
  • Controle do consumo de cotas de API


Principais algoritmos de rate limiting

Em C++, os três algoritmos clássicos mais utilizados são:



1. Token Bucket (Balde de Tokens)

O algoritmo mais popular. Representa um "balde" com tokens que são reabastecidos a uma taxa constante. Cada requisição consome um token. Se não houver tokens, a requisição é rejeitada.

#include <chrono>#include <mutex>

class TokenBucket {private: double tokens; double maxTokens; double refillRate; // tokens por segundo std::chrono::steady_clock::time_point lastRefill; std::mutex mtx;

public: TokenBucket(double maxTokens, double refillRate) : tokens(maxTokens), maxTokens(maxTokens), refillRate(refillRate) { lastRefill = std::chrono::steady_clock::now(); }

bool tryConsume() { std::lock_guard<std::mutex> lock(mtx); refill(); if (tokens >= 1.0) { tokens -= 1.0; return true; } return false; }

private: void refill() { auto now = std::chrono::steady_clock::now(); auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - lastRefill).count() / 1000.0; tokens = std::min(maxTokens, tokens + elapsed * refillRate); lastRefill = now; }};


2. Leaky Bucket (Balde Furado)

As requisições entram em uma fila (balde), que é processada a uma taxa fixa. Se o balde transbordar, as requisições são descartadas.

#include <queue>#include <chrono>

class LeakyBucket {private: std::queue<int> bucket; size_t capacity; double leakRate; // requisições por segundo std::chrono::steady_clock::time_point lastLeak; std::mutex mtx;

public: LeakyBucket(size_t capacity, double leakRate) : capacity(capacity), leakRate(leakRate) { lastLeak = std::chrono::steady_clock::now(); }

bool addRequest(int request) { std::lock_guard<std::mutex> lock(mtx); leak(); if (bucket.size() < capacity) { bucket.push(request); return true; } return false; }

private: void leak() { auto now = std::chrono::steady_clock::now(); auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - lastLeak).count() / 1000.0; size_t toRemove = static_cast<size_t>(elapsed * leakRate); while (toRemove > 0 && !bucket.empty()) { bucket.pop(); toRemove--; } lastLeak = now; }};


3. Sliding Window Log (Janela Deslizante com Log)

Armazena os carimbos de data/hora das requisições e descarta aquelas que estão fora do limite da janela. Mais preciso, mas requer mais memória.



Bibliotecas C++ populares para rate limiting

Embora a biblioteca padrão do C++ não contenha soluções prontas, existem bibliotecas testadas:

Recommendations