.NET 通用 RateLimiter 中的基本限流器:架构与算法
通用 .NET 限流组件包括四种基本算法限流器:FixedWindowRateLimiter、SlidingWindowRateLimiter、TokenBucketRateLimiter 和 ConcurrencyLimiter。第一种实现固定窗口,第二种实现滑动窗口,第三种实现令牌桶,第四种限制并发。
限流器类继承自 ReplenishingRateLimiter,它定义了通过定时器补充许可的逻辑。ConcurrencyLimiter 直接继承自 RateLimiter。构造函数接受配置参数,这些参数存储在 Options 的副本中。
所有限流器都实现了 AttemptAcquireCore(同步)、AcquireAsyncCore(异步)、Dispose/DisposeAsync。限流器还添加了 ReplenishInternal。
处理许可请求
请求分为试探请求(permitCount = 0)和真实请求(permitCount > 0)。负值会抛出 ArgumentOutOfRangeException。
处理算法:
- 验证 permitCount ≤ AutoReplenishment.MaxPermits。
- 对于试探请求:如果 availablePermits > 0 — 立即成功。
- 获取队列双端队列的锁。
- 如果 availablePermits ≥ permitCount — 授予许可,递减,并释放锁。
- 否则:同步拒绝或添加到队列(异步)。
异步方法返回 ValueTask<RateLimitLease>。队列溢出时 — 拒绝。
请求的队列结构
队列是 deque<RequestRegistration>,其中 RequestRegistration 继承自 TaskCompletionSource<RateLimitLease>。
Options 中的队列设置:
- QueueLimit:队列中 permitCount 的最大总和。
- QueueProcessingOrder:OldestFirst(先进先出,默认)或 NewestFirst(后入先出)。
当前大小:_queueTotalPermits。对 deque 加锁。
许可补充时:出队,CompleteTask 并带上成功的 Lease,递减 _queueTotalPermits。
返回 Lease 和统计信息
方法返回 RateLimitLease 的派生类:
- FixedWindowLease、SlidingWindowLease、TokenBucketLease(类似)。
- ConcurrencyLease(不同)。
计数器:_successfulAcquires、_failedAcquires(Interlocked.Increment)。
RateLimiterStatistics 提供:
- AvailablePermits。
- CurrentQueueLength。
- 计数器。
IdleDuration 属性跟踪没有请求时的空闲时间。
每个限流器的特性
FixedWindowRateLimiter
固定窗口:许可在窗口开始(permitPeriod)时补充。
_availablePermits 重置为 MaxPermits。
SlidingWindowRateLimiter
滑动窗口:跟踪 SlidingWindowSize 个片段的历史(segmentSize = permitPeriod / SlidingWindowSize)。
基于先前片段恢复。
TokenBucketRateLimiter
令牌桶:_tokens 每 ReplenishmentPeriod 补充一次,速率 = TokensPerPeriod。
基于 refillAmount 限制支出。
ConcurrencyLimiter
限制 _currentConcurrency ≤ PermitLimit。
队列在活动任务完成时(OnCompleted)启动任务。
关键点
- 通用性:基本限流器构成了 ASP.NET Core 限流的基础,并适用于 Web 场景之外。
- 队列:支持先进先出/后入先出,按总许可总和限制,异步执行。
- 试探请求:permitCount=0 用于检查而不消耗。
- 统计:原子计数器 + 实时指标。
- 补充:所有 ReplenishingRateLimiter 由定时器驱动。
— Editorial Team
暂无评论。