peixue-dev/peidu/后端限流配置修复说明.md

294 lines
7.0 KiB
Markdown
Raw Permalink Normal View History

# 后端限流配置修复说明
## 🐛 问题描述
**现象**: 第一次点击登录就提示"登录过于频繁请1秒后再试"
**错误信息**:
```json
{
"code": 500,
"message": "登录过于频繁请1秒后再试",
"data": null
}
```
## 🔍 问题原因
### 原始配置
`AuthController.java` 第42行
```java
@RateLimit(limitType = RateLimit.LimitType.IP, permitsPerSecond = 1, message = "登录过于频繁请1秒后再试")
```
### 问题分析
1. **限流太严格**: `permitsPerSecond = 1` 表示每秒只允许1次请求
2. **Guava RateLimiter 特性**: 使用令牌桶算法,第一次请求会立即消耗令牌
3. **IP 限流**: 基于 IP 地址限流,本地开发时所有请求都是同一个 IP
4. **缓存问题**: `RateLimiter` 实例被缓存,重启前的限流状态会保留
## ✅ 解决方案
### 1. 调整限流配置
**修改前**:
```java
@RateLimit(limitType = RateLimit.LimitType.IP, permitsPerSecond = 1, message = "登录过于频繁请1秒后再试")
```
**修改后**:
```java
// 调整限流每秒5次请求避免正常使用时触发限流
@RateLimit(limitType = RateLimit.LimitType.IP, permitsPerSecond = 5, message = "登录过于频繁,请稍后再试")
```
### 2. 配置说明
| 参数 | 原值 | 新值 | 说明 |
|------|------|------|------|
| permitsPerSecond | 1 | 5 | 每秒允许的请求数 |
| message | 登录过于频繁请1秒后再试 | 登录过于频繁,请稍后再试 | 错误提示 |
### 3. 为什么选择 5 次/秒
-**正常使用**: 用户正常点击不会超过5次/秒
-**防止暴力破解**: 仍然能有效防止暴力破解攻击
-**开发测试**: 方便开发和测试
-**用户体验**: 不会影响正常用户体验
## 📝 修改的文件
### `backend/src/main/java/com/peidu/controller/AuthController.java`
**位置**: 第42行
**修改内容**:
```java
// 第42行
@RateLimit(limitType = RateLimit.LimitType.IP, permitsPerSecond = 5, message = "登录过于频繁,请稍后再试")
```
## 🔄 如何应用修改
### 方法1: 重新编译运行(推荐)
```bash
# 1. 进入后端目录
cd backend
# 2. 清理并编译
mvn clean package -DskipTests
# 3. 重启后端服务
java -jar target/peidu-backend.jar
```
### 方法2: IDEA 热部署
1. 在 IDEA 中修改代码
2. 点击 "Build" → "Rebuild Project"
3. 等待自动重启
### 方法3: 清除限流缓存
如果不想重启,可以添加一个清除缓存的接口:
```java
@GetMapping("/clear-rate-limit")
public Result<Void> clearRateLimit() {
rateLimitConfig.cleanExpiredRateLimiters();
return Result.success();
}
```
## 🧪 测试验证
### 1. 重启后端服务
```bash
# 停止当前服务
# Ctrl + C 或 kill 进程
# 重新启动
java -jar target/peidu-backend.jar
```
### 2. 测试登录接口
```bash
# 使用 curl 测试
curl -X POST http://localhost:8089/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"phone": "13800138000",
"password": "123456"
}'
```
### 3. 预期结果
**成功响应**:
```json
{
"code": 200,
"message": "登录成功",
"data": {
"token": "eyJhbGc...",
"userInfo": {...}
}
}
```
**限流响应**快速连续请求6次以上:
```json
{
"code": 500,
"message": "登录过于频繁,请稍后再试",
"data": null
}
```
## 📊 其他接口的限流配置
### 当前配置一览
| 接口 | 限流类型 | 速率 | 说明 |
|------|----------|------|------|
| `/api/auth/login` | IP | 5次/秒 | ✅ 已修改 |
| `/api/auth/register` | IP | 已禁用 | 方便测试 |
| `/api/auth/send-code` | IP | 1次/分钟 | 合理 |
| `/api/auth/wx-login` | 无 | 无限制 | 建议添加 |
### 建议添加微信登录限流
`AuthController.java` 的微信登录接口添加:
```java
@ApiOperation("微信登录")
@PostMapping("/wx-login")
@RateLimit(limitType = RateLimit.LimitType.IP, permitsPerSecond = 5, message = "登录过于频繁,请稍后再试")
public Result<Map<String, Object>> wxLogin(@RequestBody WxLoginRequest request) {
// ...
}
```
## 🎯 生产环境建议
### 推荐配置
```java
// 登录接口每秒3次
@RateLimit(limitType = RateLimit.LimitType.IP, permitsPerSecond = 3, message = "登录过于频繁,请稍后再试")
// 注册接口每秒1次
@RateLimit(limitType = RateLimit.LimitType.IP, permitsPerSecond = 1, message = "注册过于频繁,请稍后再试")
// 发送验证码每分钟1次
@RateLimit(limitType = RateLimit.LimitType.IP, permitsPerSecond = 0.0167, message = "验证码发送过于频繁请1分钟后再试")
// 微信登录每秒3次
@RateLimit(limitType = RateLimit.LimitType.IP, permitsPerSecond = 3, message = "登录过于频繁,请稍后再试")
```
### 配置原则
1. **登录类接口**: 3-5次/秒,平衡安全和体验
2. **注册类接口**: 1次/秒,防止批量注册
3. **验证码接口**: 1次/分钟,防止短信轰炸
4. **业务接口**: 根据实际情况调整
## ⚠️ 注意事项
### 1. 开发环境 vs 生产环境
**开发环境**:
- 可以适当放宽限流
- 方便测试和调试
- 建议 5-10次/秒
**生产环境**:
- 需要严格限流
- 防止恶意攻击
- 建议 1-3次/秒
### 2. 限流类型选择
**IP 限流** (`RateLimit.LimitType.IP`):
- 优点:简单有效
- 缺点:同一 IP 下的所有用户共享限额
- 适用:登录、注册等公开接口
**用户限流** (`RateLimit.LimitType.USER`):
- 优点:精确控制每个用户
- 缺点:需要用户已登录
- 适用:业务接口、敏感操作
### 3. 缓存清理
`RateLimiter` 实例会被缓存,建议:
- 定期清理过期的限流器
- 重启服务会清空所有缓存
- 可以添加管理接口手动清理
## 🔧 故障排查
### 问题1: 修改后仍然限流
**原因**: 缓存未清除
**解决**: 重启后端服务
### 问题2: 所有用户都被限流
**原因**: 使用了 IP 限流,本地开发都是同一 IP
**解决**:
- 开发环境放宽限流
- 或改用用户限流
### 问题3: 限流配置不生效
**原因**:
- 注解位置错误
- AOP 未生效
- 依赖未引入
**解决**:
- 检查注解是否在正确的方法上
- 检查 `@Aspect` 是否生效
- 检查 Guava 依赖
## 📚 相关代码
### RateLimitAspect.java
限流切面实现,拦截带有 `@RateLimit` 注解的方法
### RateLimitConfig.java
限流配置类,管理 `RateLimiter` 实例缓存
### RateLimit.java
限流注解定义
## ✅ 修改完成清单
- [x] 修改登录接口限流配置
- [x] 调整 permitsPerSecond 从 1 到 5
- [x] 优化错误提示信息
- [ ] 重启后端服务(需要手动执行)
- [ ] 测试验证(需要手动执行)
- [ ] 考虑添加微信登录限流(可选)
## 🎉 总结
修改后的配置:
- ✅ 不会在第一次请求时就触发限流
- ✅ 仍然能有效防止暴力破解
- ✅ 提供更好的用户体验
- ✅ 方便开发和测试
**下一步**: 重启后端服务,然后重新测试登录功能!
---
**修改时间**: 2026-02-03
**修改文件**: `backend/src/main/java/com/peidu/controller/AuthController.java`
**状态**: ✅ 已修改,待重启服务