签入版本
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
# 5.7 接口限流(RateLimit)
|
||||
|
||||
:::tip 概述
|
||||
限流采用固定窗口计数,位于响应包裹之后、JWT 之前——**在身份解析前生效**,防住未认证的高频攻击。计数存缓存层(Redis 优先、内存降级),多实例共享。
|
||||
:::
|
||||
|
||||
## 两档配额
|
||||
|
||||
| 档位 | 配置键 | 默认 | 覆盖范围 |
|
||||
|---|---|---|---|
|
||||
| 普通 | rateLimit.limit | 120 次/窗口/IP/路径 | 其余 /api 接口 |
|
||||
| 认证 | rateLimit.authLimit | 10 次/窗口/IP | 认证入口三路径(精确匹配):`/api/login`、`/api/captcha`、`/api/oauth2/token` |
|
||||
|
||||
窗口由 `rateLimit.windowSeconds`(默认 60 秒)控制。
|
||||
|
||||
## 计数键
|
||||
|
||||
```text
|
||||
ratelimit:{ip}:{path}:{窗口起点}
|
||||
```
|
||||
|
||||
键按窗口起点对齐,窗口滚动后旧键自然过期(TTL = 窗口秒数)。计数经 `cache.Incr` 原子递增,Redis 模式下多实例共享计数。
|
||||
|
||||
## 放行与拒绝
|
||||
|
||||
```text
|
||||
放行:enable=false / 非 /api 前缀 / /api/health 豁免
|
||||
/ 阈值或窗口非正数(视为关闭)/ 计数存储故障(限流不阻断业务)
|
||||
|
||||
拒绝:写入拒绝原因 + 429 类业务响应 + Abort
|
||||
—— 不产生操作日志,metrics 归类 denied
|
||||
```
|
||||
|
||||
## 边界说明
|
||||
|
||||
当前维度是 **IP + 路径**——此环节还没有用户身份。需要用户维度限流(如单用户操作频率)的场景,应在 JWT 之后的业务层另行实现,不要往本中间件里塞。
|
||||
|
||||
## 调参建议
|
||||
|
||||
| 场景 | 建议 |
|
||||
|---|---|
|
||||
| 内网管理后台 | 保持默认或适当放大 |
|
||||
| 公网暴露 | 降低 limit,重点保护认证入口(authLimit 已较严) |
|
||||
| 压测/批量导入 | 临时调大或按 IP 白名单放行(网关层) |
|
||||
| 关闭限流 | `rateLimit.enable=false`(不建议生产) |
|
||||
|
||||
## 排查
|
||||
|
||||
| 现象 | 检查 |
|
||||
|---|---|
|
||||
| 突然全接口拒绝 | 是否有脚本高频调用占满窗口;看拒绝响应的 msg |
|
||||
| 限流不生效 | enable 开关、阈值是否非正数、是否走的非 /api 路径 |
|
||||
| 多实例计数不准 | Redis 是否降级内存(内存模式各实例独立计数) |
|
||||
|
||||
## 下一步
|
||||
|
||||
→ [5.8 演示模式](/zh/core/demo-mode.html)
|
||||
Reference in New Issue
Block a user