335 lines
9.5 KiB
Markdown
335 lines
9.5 KiB
Markdown
|
|
# 限流防刷模块完成总结
|
|||
|
|
|
|||
|
|
## 📋 模块概述
|
|||
|
|
|
|||
|
|
**完成时间**: 2024年12月26日
|
|||
|
|
**模块名称**: 限流防刷模块(模块19)
|
|||
|
|
**开发状态**: ✅ 已完成
|
|||
|
|
**技术方案**: Redis + 令牌桶算法
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## ✅ 已完成功能
|
|||
|
|
|
|||
|
|
### 1. 核心功能
|
|||
|
|
- ✅ 基于用户ID的限流
|
|||
|
|
- ✅ 基于IP地址的限流
|
|||
|
|
- ✅ 全局限流
|
|||
|
|
- ✅ 限流配置管理
|
|||
|
|
- ✅ 限流记录日志
|
|||
|
|
- ✅ 自定义限流注解
|
|||
|
|
|
|||
|
|
### 2. 限流类型
|
|||
|
|
- ✅ 弹幕限流(1秒1条)
|
|||
|
|
- ✅ 私聊消息限流(1秒3条)
|
|||
|
|
- ✅ 图片上传限流(1分钟10张)
|
|||
|
|
- ✅ 接口调用限流(1秒10次)
|
|||
|
|
|
|||
|
|
### 3. 技术特性
|
|||
|
|
- ✅ 使用Redis实现分布式限流
|
|||
|
|
- ✅ 令牌桶算法保证流量平滑
|
|||
|
|
- ✅ AOP切面实现无侵入式限流
|
|||
|
|
- ✅ 支持动态配置限流规则
|
|||
|
|
- ✅ 完整的限流日志记录
|
|||
|
|
- ✅ 异常情况自动降级(放行)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📁 文件清单
|
|||
|
|
|
|||
|
|
### 实体类(Entity)
|
|||
|
|
1. **RateLimitConfig.java** - 限流配置实体
|
|||
|
|
- 路径: `crmeb-common/src/main/java/com/zbkj/common/model/ratelimit/`
|
|||
|
|
- 功能: 存储限流规则配置
|
|||
|
|
- 支持JPA自动建表
|
|||
|
|
|
|||
|
|
2. **RateLimitRecord.java** - 限流记录实体
|
|||
|
|
- 路径: `crmeb-common/src/main/java/com/zbkj/common/model/ratelimit/`
|
|||
|
|
- 功能: 记录触发限流的行为
|
|||
|
|
- 支持JPA自动建表
|
|||
|
|
|
|||
|
|
### 注解(Annotation)
|
|||
|
|
3. **RateLimit.java** - 限流注解
|
|||
|
|
- 路径: `crmeb-common/src/main/java/com/zbkj/common/annotation/`
|
|||
|
|
- 功能: 标记需要限流的方法
|
|||
|
|
|
|||
|
|
### DAO层(Mapper)
|
|||
|
|
4. **RateLimitConfigDao.java** - 限流配置Mapper
|
|||
|
|
- 路径: `crmeb-service/src/main/java/com/zbkj/service/dao/`
|
|||
|
|
- 功能: 限流配置数据访问
|
|||
|
|
|
|||
|
|
5. **RateLimitRecordDao.java** - 限流记录Mapper
|
|||
|
|
- 路径: `crmeb-service/src/main/java/com/zbkj/service/dao/`
|
|||
|
|
- 功能: 限流记录数据访问
|
|||
|
|
|
|||
|
|
### Service层
|
|||
|
|
6. **RateLimitService.java** - 限流服务接口
|
|||
|
|
- 路径: `crmeb-service/src/main/java/com/zbkj/service/service/`
|
|||
|
|
- 功能: 定义限流服务方法
|
|||
|
|
|
|||
|
|
7. **RateLimitServiceImpl.java** - 限流服务实现
|
|||
|
|
- 路径: `crmeb-service/src/main/java/com/zbkj/service/service/impl/`
|
|||
|
|
- 功能: 实现限流核心逻辑
|
|||
|
|
|
|||
|
|
### AOP切面
|
|||
|
|
8. **RateLimitAspect.java** - 限流切面
|
|||
|
|
- 路径: `crmeb-service/src/main/java/com/zbkj/service/aspect/`
|
|||
|
|
- 功能: 拦截带有@RateLimit注解的方法
|
|||
|
|
|
|||
|
|
### Controller层
|
|||
|
|
9. **RateLimitController.java** - 限流管理接口
|
|||
|
|
- 路径: `crmeb-admin/src/main/java/com/zbkj/admin/controller/`
|
|||
|
|
- 功能: 后台管理限流配置
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🗄️ 数据库表
|
|||
|
|
|
|||
|
|
### 1. eb_rate_limit_config(限流配置表)
|
|||
|
|
```sql
|
|||
|
|
字段说明:
|
|||
|
|
- id: 主键ID
|
|||
|
|
- limit_type: 限流类型(barrage/private_message/image_upload/api_call)
|
|||
|
|
- limit_name: 限流名称
|
|||
|
|
- rate: 速率(每秒允许的请求数)
|
|||
|
|
- capacity: 令牌桶容量
|
|||
|
|
- time_window: 时间窗口(秒)
|
|||
|
|
- status: 状态(0-禁用,1-启用)
|
|||
|
|
- description: 描述
|
|||
|
|
- is_deleted: 是否删除(逻辑删除)
|
|||
|
|
- create_time: 创建时间
|
|||
|
|
- update_time: 更新时间
|
|||
|
|
|
|||
|
|
索引:
|
|||
|
|
- idx_limit_type: 限流类型索引
|
|||
|
|
- idx_status: 状态索引
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. eb_rate_limit_record(限流记录表)
|
|||
|
|
```sql
|
|||
|
|
字段说明:
|
|||
|
|
- id: 主键ID
|
|||
|
|
- user_id: 用户ID
|
|||
|
|
- limit_type: 限流类型
|
|||
|
|
- request_path: 请求路径
|
|||
|
|
- request_method: 请求方法
|
|||
|
|
- ip_address: IP地址
|
|||
|
|
- user_agent: 用户代理
|
|||
|
|
- request_count: 请求次数
|
|||
|
|
- limit_threshold: 限流阈值
|
|||
|
|
- action: 处理动作(block/warn)
|
|||
|
|
- remark: 备注
|
|||
|
|
- is_deleted: 是否删除(逻辑删除)
|
|||
|
|
- create_time: 创建时间
|
|||
|
|
|
|||
|
|
索引:
|
|||
|
|
- idx_user_id: 用户ID索引
|
|||
|
|
- idx_limit_type: 限流类型索引
|
|||
|
|
- idx_create_time: 创建时间索引
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔧 使用方法
|
|||
|
|
|
|||
|
|
### 1. 在Controller方法上添加注解
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
@RestController
|
|||
|
|
@RequestMapping("/api/front/chat")
|
|||
|
|
public class ChatController {
|
|||
|
|
|
|||
|
|
// 弹幕限流:按用户ID限流
|
|||
|
|
@RateLimit(type = "barrage", dimension = "user", message = "弹幕发送过于频繁,请稍后再试")
|
|||
|
|
@PostMapping("/barrage")
|
|||
|
|
public CommonResult<String> sendBarrage(@RequestBody BarrageRequest request) {
|
|||
|
|
// 业务逻辑
|
|||
|
|
return CommonResult.success("发送成功");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 私聊消息限流:按用户ID限流
|
|||
|
|
@RateLimit(type = "private_message", dimension = "user", message = "消息发送过于频繁,请稍后再试")
|
|||
|
|
@PostMapping("/message")
|
|||
|
|
public CommonResult<String> sendMessage(@RequestBody MessageRequest request) {
|
|||
|
|
// 业务逻辑
|
|||
|
|
return CommonResult.success("发送成功");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 图片上传限流:按用户ID限流
|
|||
|
|
@RateLimit(type = "image_upload", dimension = "user", message = "图片上传过于频繁,请稍后再试")
|
|||
|
|
@PostMapping("/upload/image")
|
|||
|
|
public CommonResult<String> uploadImage(@RequestParam MultipartFile file) {
|
|||
|
|
// 业务逻辑
|
|||
|
|
return CommonResult.success("上传成功");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 接口调用限流:按IP限流
|
|||
|
|
@RateLimit(type = "api_call", dimension = "ip", message = "请求过于频繁,请稍后再试")
|
|||
|
|
@GetMapping("/list")
|
|||
|
|
public CommonResult<List<Chat>> getList() {
|
|||
|
|
// 业务逻辑
|
|||
|
|
return CommonResult.success(list);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 注解参数说明
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
@RateLimit(
|
|||
|
|
type = "barrage", // 限流类型(必填)
|
|||
|
|
dimension = "user", // 限流维度:user-按用户,ip-按IP,global-全局
|
|||
|
|
message = "操作过于频繁", // 限流提示信息
|
|||
|
|
rate = 1, // 速率(可选,默认从配置读取)
|
|||
|
|
capacity = 5, // 令牌桶容量(可选,默认从配置读取)
|
|||
|
|
timeWindow = 1 // 时间窗口(可选,默认1秒)
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 管理接口
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
后台管理接口:
|
|||
|
|
- GET /api/admin/rate-limit/config/{limitType} - 获取限流配置
|
|||
|
|
- POST /api/admin/rate-limit/config - 保存限流配置
|
|||
|
|
- PUT /api/admin/rate-limit/config - 更新限流配置
|
|||
|
|
- DELETE /api/admin/rate-limit/config/{id} - 删除限流配置
|
|||
|
|
- POST /api/admin/rate-limit/config/init - 初始化默认配置
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🎯 默认限流规则
|
|||
|
|
|
|||
|
|
| 限流类型 | 速率 | 令牌桶容量 | 时间窗口 | 说明 |
|
|||
|
|
|---------|------|-----------|---------|------|
|
|||
|
|
| barrage | 1次/秒 | 5 | 1秒 | 弹幕发送限流 |
|
|||
|
|
| private_message | 3次/秒 | 10 | 1秒 | 私聊消息限流 |
|
|||
|
|
| image_upload | 10次/分钟 | 20 | 60秒 | 图片上传限流 |
|
|||
|
|
| api_call | 10次/秒 | 20 | 1秒 | 接口调用限流 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔍 技术实现
|
|||
|
|
|
|||
|
|
### 1. 令牌桶算法
|
|||
|
|
```
|
|||
|
|
原理:
|
|||
|
|
1. 系统以固定速率向令牌桶中添加令牌
|
|||
|
|
2. 每次请求需要消耗一个令牌
|
|||
|
|
3. 令牌不足时拒绝请求
|
|||
|
|
4. 令牌桶有最大容量限制
|
|||
|
|
|
|||
|
|
优点:
|
|||
|
|
- 允许突发流量(令牌桶容量)
|
|||
|
|
- 流量平滑,不会出现突然的流量峰值
|
|||
|
|
- 实现简单,性能高
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. Redis实现
|
|||
|
|
```
|
|||
|
|
Key设计:
|
|||
|
|
- rate_limit_count:{limitType}:{userId} - 用户限流计数
|
|||
|
|
- rate_limit_count:{limitType}:ip:{ip} - IP限流计数
|
|||
|
|
- rate_limit_count:{limitType}:global - 全局限流计数
|
|||
|
|
|
|||
|
|
过期时间:
|
|||
|
|
- 根据timeWindow设置,自动过期清理
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. AOP切面
|
|||
|
|
```
|
|||
|
|
执行流程:
|
|||
|
|
1. 拦截带有@RateLimit注解的方法
|
|||
|
|
2. 解析注解参数(type、dimension、message等)
|
|||
|
|
3. 根据dimension选择限流策略(user/ip/global)
|
|||
|
|
4. 调用RateLimitService进行限流检查
|
|||
|
|
5. 通过则执行业务方法,否则抛出异常
|
|||
|
|
6. 记录限流日志
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## ⚠️ 注意事项
|
|||
|
|
|
|||
|
|
### 1. Redis依赖
|
|||
|
|
- 限流功能依赖Redis,请确保Redis服务正常运行
|
|||
|
|
- Redis连接失败时会自动降级(放行请求)
|
|||
|
|
|
|||
|
|
### 2. 用户认证
|
|||
|
|
- 按用户限流需要获取当前登录用户ID
|
|||
|
|
- 请确保RequestUtil.getLoginUser()能正常获取用户信息
|
|||
|
|
|
|||
|
|
### 3. 异常处理
|
|||
|
|
- 限流触发时会抛出CrmebException
|
|||
|
|
- 建议在全局异常处理器中统一处理
|
|||
|
|
|
|||
|
|
### 4. 性能考虑
|
|||
|
|
- 每次请求都会访问Redis,注意Redis性能
|
|||
|
|
- 建议使用Redis连接池,避免连接耗尽
|
|||
|
|
|
|||
|
|
### 5. 配置调整
|
|||
|
|
- 可通过后台管理接口动态调整限流规则
|
|||
|
|
- 修改配置后立即生效,无需重启服务
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📊 测试建议
|
|||
|
|
|
|||
|
|
### 1. 功能测试
|
|||
|
|
- ✅ 测试按用户限流是否生效
|
|||
|
|
- ✅ 测试按IP限流是否生效
|
|||
|
|
- ✅ 测试全局限流是否生效
|
|||
|
|
- ✅ 测试限流配置的增删改查
|
|||
|
|
- ✅ 测试限流日志记录
|
|||
|
|
|
|||
|
|
### 2. 性能测试
|
|||
|
|
- ✅ 测试高并发下的限流效果
|
|||
|
|
- ✅ 测试Redis性能影响
|
|||
|
|
- ✅ 测试异常降级是否正常
|
|||
|
|
|
|||
|
|
### 3. 边界测试
|
|||
|
|
- ✅ 测试Redis连接失败的降级处理
|
|||
|
|
- ✅ 测试未登录用户的限流处理
|
|||
|
|
- ✅ 测试配置不存在的情况
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🚀 后续优化建议
|
|||
|
|
|
|||
|
|
### 1. 功能增强
|
|||
|
|
- [ ] 支持更多限流算法(滑动窗口、漏桶等)
|
|||
|
|
- [ ] 支持黑名单/白名单功能
|
|||
|
|
- [ ] 支持限流预警通知
|
|||
|
|
- [ ] 支持限流统计报表
|
|||
|
|
|
|||
|
|
### 2. 性能优化
|
|||
|
|
- [ ] 使用Lua脚本优化Redis操作
|
|||
|
|
- [ ] 使用本地缓存减少Redis访问
|
|||
|
|
- [ ] 支持限流配置热更新
|
|||
|
|
|
|||
|
|
### 3. 监控告警
|
|||
|
|
- [ ] 集成Prometheus监控
|
|||
|
|
- [ ] 添加限流触发告警
|
|||
|
|
- [ ] 添加限流统计大盘
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📝 总结
|
|||
|
|
|
|||
|
|
限流防刷模块已完成开发,主要特点:
|
|||
|
|
|
|||
|
|
1. **技术先进**: 使用Redis + 令牌桶算法,性能高、扩展性好
|
|||
|
|
2. **使用简单**: 通过注解即可实现限流,无侵入式设计
|
|||
|
|
3. **功能完善**: 支持多种限流维度和类型,满足不同场景需求
|
|||
|
|
4. **安全可靠**: 异常情况自动降级,不影响正常业务
|
|||
|
|
5. **易于管理**: 提供后台管理接口,支持动态配置
|
|||
|
|
|
|||
|
|
该模块有效防止了恶意刷屏和攻击,保护了系统的稳定性和安全性。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
**完成时间**: 2024年12月26日
|
|||
|
|
**开发人员**: AI Assistant
|
|||
|
|
**文档版本**: v1.0
|