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

294 lines
7.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 后端限流配置修复说明
## 🐛 问题描述
**现象**: 第一次点击登录就提示"登录过于频繁请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`
**状态**: ✅ 已修改,待重启服务