feat(rpm): RPM 限流模块优化

P0:
- rpm_override 嵌入 Auth Cache Snapshot,消除每请求 DB 查询 (snapshot v6→v7)
- 429 RPM 响应返回 Retry-After 头(当前分钟剩余秒数)

P1:
- ClearAll 按钮直连 DELETE API,带 loading 防重复
- 新增 GET /admin/users/:id/rpm-status 管理员 RPM 用量查询端点

优化:
- checkRPM 从级联互斥改为并行取最严,user.rpm_limit 作为全局硬上限始终生效
- Override/Group 变更后自动失效 auth cache
- fail-open 语义不变,Redis 故障不阻塞业务
This commit is contained in:
james-6-23
2026-04-23 03:33:52 +08:00
parent ef967d8f8a
commit dc5d42addc
79 changed files with 2831 additions and 140 deletions

View File

@@ -894,6 +894,8 @@ export default {
description: 'Manage your account information and settings',
accountBalance: 'Account Balance',
concurrencyLimit: 'Concurrency Limit',
rpmLimit: 'RPM Limit',
rpmUnlimited: 'Unlimited',
memberSince: 'Member Since',
overviewTitle: 'Account Overview',
overviewDescription: 'Check account status, profile sources, and common actions at a glance.',
@@ -1490,6 +1492,11 @@ export default {
copyPassword: 'Copy password',
creating: 'Creating...',
updating: 'Updating...',
form: {
rpmLimit: 'Requests Per Minute (RPM)',
rpmLimitPlaceholder: '0 = unlimited',
rpmLimitHint: 'Max requests per minute for this user; 0 = unlimited. Acts as a fallback only when the group has no rpm_limit set.'
},
columns: {
user: 'User',
id: 'ID',
@@ -1704,6 +1711,10 @@ export default {
name: 'Name',
platform: 'Platform',
rateMultiplier: 'Rate Multiplier',
rpmOverride: 'RPM Override',
rpmOverrideHint: 'Per-user RPM cap in this group; empty = group default; 0 = unlimited',
rateDefault: 'default',
rpmDefault: 'default',
type: 'Type',
accounts: 'Accounts',
capacity: 'Capacity',
@@ -1730,7 +1741,10 @@ export default {
platform: 'Platform',
rateMultiplier: 'Rate Multiplier',
status: 'Status',
exclusive: 'Exclusive Group'
exclusive: 'Exclusive Group',
rpmLimit: 'Requests Per Minute (RPM)',
rpmLimitPlaceholder: '0 = unlimited',
rpmLimitHint: 'Max requests per minute for each user in this group; 0 = unlimited. Once set, it takes over per-user rate limiting in this group (overrides the user-level rpm_limit fallback).'
},
enterGroupName: 'Enter group name',
optionalDescription: 'Optional description',
@@ -1762,6 +1776,12 @@ export default {
rateMultipliers: 'Rate Multipliers',
rateMultipliersTitle: 'Group Rate Multipliers',
addUserRate: 'Add User Rate Multiplier',
rpmOverrides: 'RPM Overrides',
rpmOverridesTitle: 'Group RPM Overrides',
addUserRpm: 'Add User RPM Override',
noRpmOverrides: 'No users have an RPM override yet',
rpmSaved: 'RPM overrides saved',
groupRpmDefault: 'Group default RPM',
searchUserPlaceholder: 'Search user email...',
noRateMultipliers: 'No user rate multipliers configured',
rateUpdated: 'Rate multiplier updated',
@@ -4503,6 +4523,8 @@ export default {
defaultBalanceHint: 'Initial balance for new users',
defaultConcurrency: 'Default Concurrency',
defaultConcurrencyHint: 'Maximum concurrent requests for new users',
defaultUserRpmLimit: 'Default User RPM Limit',
defaultUserRpmLimitHint: 'Default max requests per minute for new users; 0 = unlimited. Only applied at new user creation.',
defaultSubscriptions: 'Default Subscriptions',
defaultSubscriptionsHint: 'Auto-assign these subscriptions when a new user is created or registered',
addDefaultSubscription: 'Add Default Subscription',

View File

@@ -898,6 +898,8 @@ export default {
description: '管理您的账户信息和设置',
accountBalance: '账户余额',
concurrencyLimit: '并发限制',
rpmLimit: 'RPM 限制',
rpmUnlimited: '不限制',
memberSince: '注册时间',
overviewTitle: '账户总览',
overviewDescription: '快速查看账号状态、资料来源与常用设置。',
@@ -1589,7 +1591,10 @@ export default {
balanceLabel: '余额',
concurrencyLabel: '并发数',
statusLabel: '状态',
selectStatus: '选择状态'
selectStatus: '选择状态',
rpmLimit: '每分钟请求数 (RPM)',
rpmLimitPlaceholder: '0 表示不限制',
rpmLimitHint: '该用户每分钟最大请求数0 = 不限制;仅在所用分组未设置 rpm_limit 时作为兜底生效'
},
adjustBalance: '调整余额',
adjustConcurrency: '调整并发数',
@@ -1756,6 +1761,10 @@ export default {
name: '名称',
platform: '平台',
rateMultiplier: '费率倍数',
rpmOverride: 'RPM 覆盖',
rpmOverrideHint: '该用户在此分组的 RPM 上限;留空 = 使用分组默认0 = 不限制',
rateDefault: '默认',
rpmDefault: '默认',
exclusive: '独占',
type: '类型',
priority: '优先级',
@@ -1790,6 +1799,9 @@ export default {
descriptionPlaceholder: '请输入描述(可选)',
rateMultiplierLabel: '费率倍数',
rateMultiplierHint: '1.0 = 标准费率0.5 = 半价2.0 = 双倍',
rpmLimit: '每分钟请求数 (RPM)',
rpmLimitPlaceholder: '0 表示不限制',
rpmLimitHint: '每用户在本分组每分钟最大请求数0 = 不限制;一旦设置即接管该用户的限流(覆盖用户级 rpm_limit',
exclusiveLabel: '专属分组',
exclusiveHint: '专属分组,可以手动指定给用户',
platformLabel: '平台限制',
@@ -1859,6 +1871,12 @@ export default {
rateMultipliers: '专属倍率',
rateMultipliersTitle: '分组专属倍率管理',
addUserRate: '添加用户专属倍率',
rpmOverrides: '专属 RPM',
rpmOverridesTitle: '分组专属 RPM 管理',
addUserRpm: '添加用户专属 RPM',
noRpmOverrides: '暂无用户设置了专属 RPM',
rpmSaved: '专属 RPM 已保存',
groupRpmDefault: '分组默认 RPM',
searchUserPlaceholder: '搜索用户邮箱...',
noRateMultipliers: '暂无用户设置了专属倍率',
rateUpdated: '专属倍率已更新',
@@ -4668,6 +4686,8 @@ export default {
defaultBalanceHint: '新用户的初始余额',
defaultConcurrency: '默认并发数',
defaultConcurrencyHint: '新用户的最大并发请求数',
defaultUserRpmLimit: '默认用户 RPM 限制',
defaultUserRpmLimitHint: '新用户默认每分钟最大请求数0 = 不限制;仅作用于新用户创建时初始化',
defaultSubscriptions: '默认订阅列表',
defaultSubscriptionsHint: '新用户创建或注册时自动分配这些订阅',
addDefaultSubscription: '添加默认订阅',