C# Polly RateLimitAsync策略过早触发限流问题排查
问题原因
你对Polly速率限制策略的默认实现逻辑理解存在偏差:
- 你调用的双参数
Policy.RateLimitAsync(numberOfExecutions, perTimeSpan)重载,底层采用令牌桶算法,默认将最大突发容量(桶初始令牌数)设置为1,而非你传入的允许执行总次数。 - 你配置的规则是10秒5次调用,对应令牌补充速率为每2秒1个。初始化时桶内仅1个令牌,因此第一次调用消耗令牌成功后,后续请求必须等令牌匀速补充(每2秒补1个)才能放行,中间的所有请求都会被限流,和你观察到的“1次成功后连续限流、约2秒后再成功1次”的现象完全吻合。
- 你尝试替换
ExecuteAndCaptureAsync为ExecuteAsync加try-catch的写法,仅改变了异常捕获的方式,底层限流计数逻辑没有任何变化,因此运行结果不会有差异。
修复方案
使用带maxBurst参数的三参数重载创建限流策略,将最大突发容量设置为和周期内允许总次数一致,即可实现你预期的“10秒内最多连续5次调用”的效果:
public RateLimiter(int numberOfExecutions, TimeSpan perTimeSpan, Action<string> rateLimitedAction) { // 第三个参数传入numberOfExecutions,将桶初始令牌数设为周期允许的最大次数,支持突发满额调用 _throttlingPolicy = Policy.RateLimitAsync(numberOfExecutions, perTimeSpan, numberOfExecutions); _rateLimitedAction = rateLimitedAction; }
三参数重载的参数含义:
numberOfExecutions:指定统计周期内允许的总调用次数,决定令牌补充速率perTimeSpan:统计周期长度maxBurst:令牌桶最大容量,即初始化时预存的令牌数,决定允许的最大突发调用量
验证说明
修改后重新运行测试代码,会先连续返回5次正常结果,第6次及后续请求在令牌耗尽后会触发限流,等待配额补充后才会放行,和你的预期行为一致。
内容的提问来源于stack exchange,提问作者Arthur Rey
相关产品推荐
相关产品推荐

