C++中的速率限制:请求限制完整指南
速率限制(请求速度限制)是保护服务器、API和分布式系统免受过载、DDoS攻击和突发流量冲击的关键机制。在C++中,实现速率限制需要高效的算法和正确的库选择。本文将介绍主要方法、流行库,并提供现成的代码示例。
什么是速率限制,为什么需要它?
速率限制规定了客户端或系统在特定时间段内可以执行的最大请求数。主要目标包括:
- 防止滥用和服务器过载
- 确保用户之间资源的公平分配
- 阻止DDoS攻击和暴力破解攻击
- 控制API配额消耗
主要的速率限制算法
在C++中,最常使用三种经典算法:
1. 令牌桶
最流行的算法。它像一个“桶”,其中令牌以恒定速率填充。每个请求消耗一个令牌。如果没有令牌,请求将被拒绝。
#include <chrono>#include <mutex>
class TokenBucket {private: double tokens; double maxTokens; double refillRate; // 每秒令牌数 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. 漏桶
请求进入一个队列(桶),该队列以固定速率处理。如果桶溢出,请求将被丢弃。
#include <queue>#include <chrono>
class LeakyBucket {private: std::queue<int> bucket; size_t capacity; double leakRate; // 每秒请求数 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. 滑动窗口日志
存储请求的时间戳,并丢弃超出窗口范围的请求。更精确,但需要更多内存。
流行的C++速率限制库
虽然C++标准库不包含现成的解决方案,但存在一些经过验证的库:
-
图书馆中也有
推荐