
系统设计:分布式限流器
算法比较
令牌桶:允许突发到桶容量,平滑平均速率
漏桶:以恒定速率处理,队列吸收突发
固定窗口:简单但允许在窗口边界出现 2 倍突发
滑动窗口:更精确,防止边界突发

令牌桶实现(Redis + Lua)
local key = KEYS[1]
local capacity = tonumber(ARGV[1])
local refill_rate = tonumber(ARGV[2])
local requested = tonumber(ARGV[3])
local now = tonumber(ARGV[4])
local bucket = redis.call('HMGET', key, 'tokens', 'last_refill')
local tokens = tonumber(bucket[1]) or capacity
local last_refill = tonumber(bucket[2]) or now
local elapsed = now - last_refill
local new_tokens = math.min(capacity, tokens + elapsed * refill_rate)
if new_tokens >= requested then
redis.call('HMSET', key, 'tokens', new_tokens - requested, 'last_refill', now)
redis.call('EXPIRE', key, math.ceil(capacity / refill_rate) + 1)
return {1, math.floor(new_tokens - requested)}
else
redis.call('HMSET', key, 'tokens', new_tokens, 'last_refill', now)
return {0, math.floor(new_tokens)}
end

滑动窗口(使用有序集合)
async function slidingWindowRateLimit(userId: string, limit: number, windowMs: number): Promise<boolean> {
const key = `sw:${userId}`;
const now = Date.now();
const windowStart = now - windowMs;
const pipeline = redis.multi();
pipeline.zRemRangeByScore(key, '-inf', windowStart.toString());
pipeline.zCard(key);
pipeline.zAdd(key, { score: now, value: `${now}:${Math.random()}` });
pipeline.pExpire(key, windowMs);
const results = await pipeline.exec();
const count = results[1] as number;
return count < limit;
}

多层限流
async function multiTierLimit(userId: string): Promise<void> {
const limits = [
{ key: `sec:${userId}`, limit: 10, window: 1000 },
{ key: `min:${userId}`, limit: 100, window: 60000 },
{ key: `hour:${userId}`, limit: 1000, window: 3600000 },
];
for (const { key, limit, window } of limits) {
const allowed = await slidingWindowRateLimit(key, limit, window);
if (!allowed) throw new TooManyRequestsError('Rate limit exceeded');
}
}
API 网关中间件
app.use(async (req, res, next) => {
const identifier = req.user?.id || req.ip;
const result = await limiter.isAllowed(identifier, 100, 60);
res.setHeader('X-RateLimit-Limit', 100);
res.setHeader('X-RateLimit-Remaining', result.remaining);
if (!result.allowed) {
return res.status(429).json({ error: 'Too Many Requests' });
}
next();
});
分布式限流器是保护大规模 API 的核心基础设施组件。