C# 实现简单的接口限流工具(令牌桶算法)

简介: 基于令牌桶算法实现接口限流,通过控制令牌生成速率与桶容量,防止高频请求压垮服务,适用于Web及后端系统,保障接口稳定。

基于令牌桶算法实现接口限流,防止接口被高频请求压垮,适用于 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);
    }
}

}

相关文章
|
前端开发 NoSQL JavaScript
常见接口和服务幂等性问题及解决方案
常见接口和服务幂等性问题及解决方案
1035 0
|
监控 Docker 索引
docker安装filebeat 进行日志收集
docker安装filebeat 进行日志收集
1420 0
docker安装filebeat 进行日志收集
|
消息中间件
RabbitMQ.Client.Exceptions.BrokerUnreachableException:“None of the specified endpoints were reachabl
RabbitMQ.Client.Exceptions.BrokerUnreachableException:“None of the specified endpoints were reachabl
818 0
|
8月前
|
JSON API 开发者
闲鱼商品详情API数据解析(附代码)
闲鱼商品详情API(goodfish.item_get)支持通过商品ID获取标题、价格、描述等信息,适用于比价、推荐系统及市场分析。接口支持GET/POST请求,返回JSON格式数据,并提供Python调用示例,便于开发者快速集成。
|
11月前
|
安全
区分ConnectTimeout错误和ConnectionError异常在使用中的不同。
总结一下,这两个问题就像是你试图拨打一个电话。ConnectTimeout错误就好比你拨通了电话,但另一端没有接听;ConnectionError异常则好比你的电话根本没法拨出去,或者你拨错了号码——甚至是你根本就没拿到电话。所以,在下一次遇到类似问题的时候,希望你能想起这个比喻,然后灵活应对。
457 34
|
监控 关系型数据库 MySQL
MySQL自增ID耗尽应对策略:技术解决方案全解析
在数据库管理中,MySQL的自增ID(AUTO_INCREMENT)属性为表中的每一行提供了一个唯一的标识符。然而,当自增ID达到其最大值时,如何处理这一情况成为了数据库管理员和开发者必须面对的问题。本文将探讨MySQL自增ID耗尽的原因、影响以及有效的应对策略。
731 3
|
Kubernetes 监控 Docker
深入解析 Kubernetes 架构:掌握主节点、工作节点和容器运行时
深入解析 Kubernetes 架构:掌握主节点、工作节点和容器运行时
761 0
|
JavaScript API
Vue学习之--------列表排序(ffilter、sort、indexOf方法的使用)、Vue检测数据变化的原理(2022/7/15)
这篇博客文章讲解了Vue中列表排序的方法,使用`filter`、`sort`和`indexOf`等数组方法进行数据的过滤和排序,并探讨了Vue检测数据变化的原理,包括Vue如何通过setter和数组方法来实现数据的响应式更新。
Vue学习之--------列表排序(ffilter、sort、indexOf方法的使用)、Vue检测数据变化的原理(2022/7/15)
|
缓存 前端开发 Java
Spring Boot中防止接口重复提交
Spring Boot中防止接口重复提交
2237 0
|
存储 NoSQL MongoDB
深入详解MongoDB索引的数据组织结构
深入详解MongoDB索引的数据组织结构