mcpField
R
rate-limiting

rate-limiting

github.com/claude-dev-suite开发4640 次安装2 天前更新
代码仓库

关于 rate-limiting

面向开发者的限流实现参考,介绍 Express 和 Spring Boot 示例、Redis 滑动窗口及常见算法,帮助选择限流策略并配置响应头。

主要功能

  1. 01Express 限流示例
  2. 02Redis 滑动窗口实现
  3. 03限流算法比较
  4. 04Spring Boot 与 Bucket4j 示例
  5. 05响应头与生产检查清单

适用场景

  1. 01为 API 添加请求速率限制
  2. 02在多服务器部署中使用 Redis 限流
  3. 03比较不同限流算法
  4. 04配置 429 响应及重试提示

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/claude-dev-suite/claude-dev-suite --skill rate-limiting

安装后在 Claude Code 中输入/rate-limiting确认已加载。

详细介绍

速率限制

Express (express-rate-limit)

import rateLimit from 'express-rate-limit';
import RedisStore from 'rate-limit-redis';
import { createClient } from 'redis';

const redis = createClient({ url: process.env.REDIS_URL });

// Global rate limit
const globalLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  limit: 100,
  standardHeaders: 'draft-7',
  legacyHeaders: false,
  store: new RedisStore({ sendCommand: (...args) => redis.sendCommand(args) }),
  message: { error: 'Too many requests, try again later' },
});

app.use(globalLimiter);

// Stricter limit on auth endpoints
const authLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  limit: 5,
  keyGenerator: (req) => req.body.email || req.ip, // By email, not just IP
  store: new RedisStore({ sendCommand: (...args) => redis.sendCommand(args) }),
});

app.use('/api/auth/login', authLimiter);

Redis 滑动窗口(自定义)

async function isRateLimited(key: string, limit: number, windowSec: number): Promise<boolean> {
  const now = Date.now();
  const windowStart = now - windowSec * 1000;

  const multi = redis.multi();
  multi.zRemRangeByScore(key, 0, windowStart);    // Remove old entries
  multi.zAdd(key, { score: now, value: `${now}` });
  multi.zCard(key);                                  // Count in window
  multi.expire(key, windowSec);

  const results = await multi.exec();
  const count = results![2] as number;
  return count > limit;
}

// Usage
if (await isRateLimited(`rl:${userId}`, 100, 60)) {
  return res.status(429).json({ error: 'Rate limit exceeded' });
}

算法比较

算法精确度内存占用最适用场景
固定窗口低(窗口边界处会突发)极低简单的 API
滑动窗口日志高中等精确限流
滑动窗口计数器中等低平衡精确度与内存占用
令牌桶中等低支持突发流量的 API

Spring Boot (Bucket4j)

@Bean
public FilterRegistrationBean<RateLimitFilter> rateLimitFilter() {
    var filter = new RateLimitFilter(
        Bandwidth.classic(100, Refill.intervally(100, Duration.ofMinutes(1)))
    );
    var registration = new FilterRegistrationBean<>(filter);
    registration.addUrlPatterns("/api/*");
    return registration;
}

响应标头

// Standard rate limit headers (RFC draft-7)
res.set({
  'RateLimit-Limit': '100',
  'RateLimit-Remaining': `${remaining}`,
  'RateLimit-Reset': `${resetTimestamp}`,
  'Retry-After': `${retryAfterSeconds}`, // On 429 responses
});

反模式

反模式修复方法
多服务器环境下使用内存限流使用基于 Redis 的存储
仅按 IP 限流同时按用户 ID 或 API 密钥限流
响应中没有速率限制标头发送 RateLimit-* 标头,便于客户端了解限流情况
所有端点使用相同的限制对身份验证、webhook 和高开销操作设置更严格的限制
429 响应中没有 Retry-After添加 Retry-After 标头

生产环境检查清单

  • 在分布式部署中使用基于 Redis 的限流
  • 按端点配置速率限制
  • 在响应中添加标准速率限制标头
  • 在 429 响应中添加 Retry-After 标头
  • 按用户 ID 限流(不只是 IP)
  • 监控:触发限流的频率

评论

支持 Markdown