Fix atomic multi-dimension rate limiting#39
Open
isCharles wants to merge 1 commit into
Open
Conversation
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 调用中执行。