Limitación de tasa en C++: guía completa para limitar solicitudes
La limitación de tasa (rate limiting) es un mecanismo críticamente importante para proteger servidores, API y sistemas distribuidos de sobrecargas, ataques DDoS y picos repentinos de tráfico. En C++, la implementación de la limitación de tasa requiere algoritmos eficientes y la elección correcta de bibliotecas. En este artículo, analizaremos los enfoques principales, las bibliotecas populares y proporcionaremos ejemplos de código listos para usar.
¿Qué es la limitación de tasa y por qué es necesaria?
La limitación de tasa establece el número máximo de solicitudes que un cliente o sistema puede realizar en un período de tiempo determinado. Los objetivos principales son:
- Protección contra abusos y sobrecarga del servidor
- Garantizar una distribución uniforme de los recursos entre los usuarios
- Prevención de ataques DDoS y ataques de fuerza bruta
- Control del consumo de cuotas de API
Algoritmos principales de limitación de tasa
En C++, los tres algoritmos clásicos más utilizados son:
1. Token Bucket (Cubo de fichas)
El algoritmo más popular. Representa un "cubo" con fichas que se reponen a una velocidad constante. Cada solicitud toma una ficha. Si no hay fichas, la solicitud es rechazada.
#include <chrono>#include <mutex>
class TokenBucket {private: double tokens; double maxTokens; double refillRate; // fichas 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 (Cubo con fugas)
Las solicitudes llegan a una cola (cubo) que se procesa a una velocidad fija. Si el cubo se desborda, las solicitudes se descartan.
#include <queue>#include <chrono>
class LeakyBucket {private: std::queue<int> bucket; size_t capacity; double leakRate; // solicitudes 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 (Ventana deslizante con registro)
Almacena marcas de tiempo de las solicitudes y descarta aquellas que quedan fuera de la ventana. Es más preciso, pero requiere más memoria.
Bibliotecas populares de C++ para limitación de tasa
Aunque la biblioteca estándar de C++ no contiene soluciones listas para usar, existen bibliotecas probadas:
-
También en la biblioteca
Rate Limiting en JavaScript (Node.js): Guía completa de la biblioteca express-rate-limit
ORM para JavaScript (Node.js): comparación y ejemplos
iTextSharp para C# (.NET): guía completa con ejemplos
Rate Limiting en Go: guía para limitar la velocidad de las solicitudes
Tokens JWT en Kotlin: generación, verificación y uso con io.jsonwebtoken
Recommendations