Fix atomic multi-dimension rate limiting - #39
Merged
Snailclimb merged 1 commit intoAug 13, 2026
Merged
Conversation
Snailclimb
requested changes
Jul 24, 2026
Snailclimb
left a comment
Owner
There was a problem hiding this comment.
当前实现存在会影响限流准确性的阻断问题,建议修改后再合并。
-
[P1]
app/src/main/resources/scripts/rate_limit_single.lua:33-51:第一阶段在所有维度通过前就执行zremrangebyscore。如果当前维度回收到令牌并通过、后续维度返回-i,回收后的current_val不会写回,但过期记录已经消失,令牌会丢失到 value key 的 TTL 到期。建议检查阶段只读取和计算,所有规则通过后再统一删除过期记录、扣减和写回。 -
[P1]
RateLimitIntegrationTest仍被@Disabled,而RateLimitScriptTest不执行 Lua。单维拒绝现在返回-1,测试第 80、117 行仍断言旧值0,启用后会失败。请增加可在 CI 中执行的真实 Redis 回归测试,并覆盖“前一维度有过期令牌、后一维度拒绝”的场景。
隔离 Redis 7 复现结果:第一次调用返回 -2 后,global 的过期记录已被删除但 value 仍为 0;第二次调用因此返回 -1。
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.
Summary
@RateLimitrules for a method in a single Redis Lua call.Root cause
The previous aspect loop called the Lua script once per
@RateLimitrule. If an earlier rule such asGLOBALsucceeded and a later rule such asIPfailed, the rejected request had already consumed the global token.Validation
.\gradlew.bat :app:compileJava :app:compileTestJava.\gradlew.bat :app:test --tests "interview.guide.common.aspect.RateLimitScriptTest"Note:
RateLimitIntegrationTestremains disabled because it requires a live Redis instance, but its multi-rule case now asserts that a later rejected dimension does not deduct earlier dimensions.之前
RateLimitAspect会按@RateLimit规则逐条循环调用 Lua 脚本。如果前面的规则,例如GLOBAL,已经扣减成功,但后面的规则,例如IP,限流失败,那么这次请求虽然最终被拒绝,却已经消耗了全局令牌。如果有人疯狂刷接口,即使这些请求最终都被 IP 限流拒绝,也可能持续消耗 GLOBAL 令牌。结果是其他正常用户更早遇到全局限流。统计上也有问题。
更改
@RateLimit规则合并到一次 Redis Lua 调用中执行。