基于令牌桶算法实现接口限流,防止接口被高频请求压垮,适用于 Web 和服务端项目。
using System.Threading;
public class TokenBucketLimiter
{
// 令牌桶容量
private readonly int _capacity;
// 令牌生成速率(每秒生成多少个)
private readonly double _tokenRatePerSecond;
// 当前令牌数
private double _currentTokens;
// 上次生成令牌的时间
private DateTime _lastRefillTime;
private readonly object _lockObj = new();
public TokenBucketLimiter(int capacity, double tokenRatePerSecond)
{
_capacity = capacity;
_tokenRatePerSecond = tokenRatePerSecond;
_currentTokens = capacity;
_lastRefillTime = DateTime.Now;
}
// 尝试获取令牌
public bool TryAcquire(int tokens = 1)
{
lock (_lockObj)
{
// 补充令牌
RefillTokens();
if (_currentTokens >= tokens)
{
_currentTokens -= tokens;
return true;
}
return false;
}
}
// 补充令牌
private void RefillTokens()
{
var now = DateTime.Now;
var elapsedSeconds = (now - _lastRefillTime).TotalSeconds;
var newTokens = elapsedSeconds * _tokenRatePerSecond;
_currentTokens = Math.Min(_currentTokens + newTokens, _capacity);
_lastRefillTime = now;
}
// 调用示例
public static void TestLimiter()
{
// 容量10,每秒生成5个令牌
var limiter = new TokenBucketLimiter(10, 5);
for (int i = 0; i < 20; i++)
{
var canAccess = limiter.TryAcquire();
Console.WriteLine($"请求{i + 1}: {(canAccess ? "成功" : "限流")}");
Thread.Sleep(100);
}
}
}