feat: 为分组/用户新增 RPM 限流(分组优先,用户兜底)#1743
Closed
james-6-23 wants to merge 1 commit intoWei-Shaw:mainfrom
Closed
Conversation
- 新增 Group.RPMLimit 与 User.RPMLimit 字段(migrations 108/109),
限流计数以 (user, group) 或 user 聚合,杜绝多 Key 绕过
- BillingCacheService.checkRPM 采用 fallback 语义:分组设置 rpm_limit 则按分组计数,
否则回落到用户级;任一超限返回 429 并区分 GROUP_RPM_EXCEEDED / USER_RPM_EXCEEDED
- 新增 UserRPMCache(Redis 键 rpm:ug:{uid}:{gid}:{min} 与 rpm:u:{uid}:{min}),
以 TxPipeline(INCR+EXPIRE) 原子计数,Redis 服务端时间对齐分钟窗口,故障一律 fail-open
- APIKeyAuthSnapshot 快照带上 Group/User RPMLimit,版本 bump 至 v7,
用户级变更会触发 auth cache 失效
- 系统设置新增 default_user_rpm_limit:管理员 / 自助注册 / OAuth 自动注册
未显式指定 rpm_limit 时自动套用
- 前端:分组编辑、用户创建/编辑、系统设置"用户默认设置"均新增 RPM 输入项
及中英文文案
1e0d466 to
4d0483f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
变更说明
本次新增能力:为上游请求加入两级 RPM(每分钟请求数)限流,分别作用于分组与用户,采用 fallback 语义——分组设了 rpm_limit
就按分组限;分组没设,则按用户级 rpm_limit 兜底;两者都为 0 则不限流。
背景与动机
设计决策
限流判定采用 fallback,不做两层独立叠加(避免"取较小者"带来的认知负担):
┌────────────────┬───────────────┬────────────────┐
│ Group.RPMLimit │ User.RPMLimit │ 生效 RPM │
├────────────────┼───────────────┼────────────────┤
│ > 0 │ 任意 │ 按分组 │
├────────────────┼───────────────┼────────────────┤
│ 0 │ > 0 │ 按用户(兜底) │
├────────────────┼───────────────┼────────────────┤
│ 0 │ 0 │ 不限流 │
└────────────────┴───────────────┴────────────────┘
计数粒度按 user 聚合(不是 api_key),杜绝"同一用户建多个 Key 绕过限流"的路径。
修复内容
后端
前端
验证结果
后端
go build ./... # ✅
go vet ./... # ✅
go test ./internal/service/... ./internal/handler/... ./internal/repository/... # ✅
前端
vue-tsc --noEmit # ✅
覆盖的风险场景
影响范围