基于Redis和令牌桶算法的分布式限流系统,支持IP、用户ID、路径等多维度限流,提供完整的管理界面和统计功能。
- 多维度限流: 默认基于路径限流,可选择启用IP和用户ID维度
- 多重校验: 启用多个维度时,请求需通过所有维度的限流检查
- 令牌桶算法: 基于Redis的分布式令牌桶实现,支持突发流量
- Ant路径匹配: 支持
?、*、**通配符的路径模式匹配 - HTTP方法过滤: 可选择性地对特定HTTP方法进行限流
- 详细日志记录: 记录限流阻止的详细信息,便于分析和监控
- 实时统计: 请求数、阻止数、通过率等实时统计
- 维度统计: IP和用户级别的详细统计信息
- 图表展示: 请求趋势图和统计图表
- 数据导出: 支持CSV格式数据导出
- 规则管理: 可视化的限流规则配置和管理
- 实时监控: 限流状态和统计信息的实时监控
- 测试工具: 内置的限流功能测试工具
- 响应式设计: 支持PC和移动端访问
- Spring Boot 2.6.13: 应用框架
- Redis: 分布式缓存和限流状态存储
- Freemarker: 模板引擎
- Jackson: JSON序列化
- Lua脚本: 原子性的令牌桶操作
- HTML5 + CSS3: 响应式界面
- JavaScript (ES6): 交互逻辑
- Axios: HTTP客户端
- Chart.js: 图表展示
- Java 8+
- Redis 3.0+
- Maven 3.6+
redis-server
编辑 src/main/resources/application.properties:
# Redis配置 spring.redis.host=localhost spring.redis.port=6379 spring.redis.database=0 # 应用端口 server.port=8080
mvn spring-boot:run
- 管理首页: http://localhost:8080/ratelimit/
- 规则配置: http://localhost:8080/ratelimit/config
- 统计分析: http://localhost:8080/ratelimit/stats
- 功能测试: http://localhost:8080/test.html
-
基本配置
- 规则名称: 便于识别的规则名称
- 路径模式: 支持Ant风格通配符
?: 匹配单个字符*: 匹配任意字符(除路径分隔符)**: 匹配任意路径
- HTTP方法: 可选择特定的HTTP方法
-
限流维度
- 路径限流: 默认启用,基于请求路径进行限流
- IP维度限流: 可选启用,对每个IP地址单独限流
- 用户维度限流: 可选启用,对每个用户ID单独限流
- 多维度校验: 启用多个维度时,请求需要通过所有维度的检查
-
令牌桶配置
- 令牌桶容量: 最大令牌数,决定突发请求处理能力
- 令牌补充速率: 每秒补充的令牌数,决定平均限流速率
- 时间窗口: 令牌补充的时间间隔
-
维度限流配置
- IP维度限流: 可单独配置每个IP的限流参数
- 用户维度限流: 可单独配置每个用户的限流参数
规则名称: API接口限流
路径模式: /api/**
HTTP方法: GET, POST
限流类型: IP限流
令牌桶容量: 20
令牌补充速率: 10
时间窗口: 1秒
启用IP维度限流: 是
IP请求限制: 10
规则名称: 用户操作限流
路径模式: /user/*/action
HTTP方法: POST
限流类型: 用户限流
令牌桶容量: 5
令牌补充速率: 2
时间窗口: 1秒
启用用户维度限流: 是
用户请求限制: 2
规则名称: 高频接口限流
路径模式: /high-frequency
HTTP方法: 全部
限流类型: 路径限流
令牌桶容量: 100
令牌补充速率: 50
时间窗口: 1秒
令牌桶算法通过控制令牌的生成和消费来实现限流:
- 令牌生成: 按固定速率向桶中添加令牌
- 令牌消费: 每个请求消费一个令牌
- 桶容量限制: 桶中令牌数不超过最大容量
- 请求处理: 有令牌则允许请求,无令牌则拒绝
- 平滑限流: 允许突发流量,但长期平均速率受限
- 灵活配置: 可独立配置桶容量和补充速率
- 分布式支持: 基于Redis实现分布式一致性
- 高性能: Lua脚本保证原子性操作
-- 获取当前令牌数和最后补充时间 local bucket = redis.call('HMGET', key, 'tokens', 'last_refill') local current_tokens = tonumber(bucket[1]) or capacity local last_refill = tonumber(bucket[2]) or now -- 计算需要补充的令牌数 local elapsed = math.max(0, now - last_refill) local tokens_to_add = math.floor(elapsed / interval * tokens) current_tokens = math.min(capacity, current_tokens + tokens_to_add) -- 判断是否允许请求 local allowed = 0 if current_tokens >= requested then current_tokens = current_tokens - requested allowed = 1 end -- 更新令牌桶状态 redis.call('HMSET', key, 'tokens', current_tokens, 'last_refill', now) return {allowed, current_tokens}
GET /ratelimit/api/rules- 获取所有规则GET /ratelimit/api/rules/{id}- 获取单个规则POST /ratelimit/api/rules- 创建/更新规则DELETE /ratelimit/api/rules/{id}- 删除规则PUT /ratelimit/api/rules/{id}/toggle- 启用/禁用规则
GET /ratelimit/api/stats- 获取所有统计GET /ratelimit/api/stats/global- 获取全局统计GET /ratelimit/api/stats/{ruleId}/detailed- 获取详细统计GET /ratelimit/api/stats/{ruleId}/ip- 获取IP统计GET /ratelimit/api/stats/{ruleId}/user- 获取用户统计
DELETE /ratelimit/api/stats- 重置所有统计DELETE /ratelimit/api/reset- 重置限流状态
访问 http://localhost:8080/test.html 使用内置测试工具:
- 单个请求测试: 发送单个请求验证限流效果
- 批量请求测试: 按间隔发送多个请求
- 并发请求测试: 同时发送多个请求
- 场景测试: 预设的测试场景
- 正常访问测试
- 突发流量测试
- 攻击模拟测试
- 多用户测试
系统提供了多个测试接口:
GET /test/get- GET请求测试POST /test/post- POST请求测试GET /test/api/data- API接口测试GET /test/user/{userId}- 用户接口测试GET /test/high-frequency- 高频接口测试
- 请求总数: 系统处理的总请求数
- 允许请求数: 通过限流检查的请求数
- 阻止请求数: 被限流阻止的请求数
- 阻止率: 被阻止请求的百分比
- 请求频率: 每秒请求数
- IP统计: 每个IP的请求统计
- 用户统计: 每个用户的请求统计
- 规则统计: 每个规则的执行统计
支持将统计数据导出为CSV格式,便于进一步分析。
- 实现
RateLimitStrategy接口 - 添加
@Component注解 - 实现必要的方法:
generateKey(): 生成限流键getRequestLimit(): 获取请求限制supports(): 检查是否支持extractIdentifier(): 提取标识符
- 扩展
DetailedRateLimitStats模型 - 修改
RedisRateLimitStatsService实现 - 更新前端展示逻辑
- Redis连接: 确保Redis服务正常运行且连接配置正确
- 时钟同步: 分布式环境下确保各节点时钟同步
- 内存使用: 监控Redis内存使用,及时清理过期数据
- 性能调优: 根据实际负载调整令牌桶参数
- 规则优先级: 数字越小优先级越高,合理设置规则优先级
MIT License
欢迎提交Issue和Pull Request来改进这个项目。