前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【愚公系列】2023年10月 .NET CORE工具案例-DotNetRateLimiter限流库

【愚公系列】2023年10月 .NET CORE工具案例-DotNetRateLimiter限流库

作者头像
愚公搬代码
发布2025-06-01 12:32:50
发布2025-06-01 12:32:50
5700
代码可运行
举报
文章被收录于专栏:历史专栏历史专栏
运行总次数:0
代码可运行

🚀前言

限流是一种限制系统中某些操作的频率或数量的技术。在高负载情况下,系统可能无法处理大量的请求,导致响应时间变慢甚至宕机。为了避免这种情况的发生,可以通过限流技术来限制请求的数量或频率,使系统可以平稳运行。限流可以在不同的层面上实现,如应用程序层面、网络层面以及硬件层面。

DotNetRateLimiter是一个开源的.NET Core限流库,用于帮助开发人员实现在高并发环境下的请求限制和流量控制。这个库实现了常见的限流算法,包括滑动窗口、令牌桶、漏桶等,可以根据具体的业务场景选择不同的算法进行限流。

DotNetRateLimiter库提供了易于使用的API,使得开发人员可以轻松地将限流逻辑集成到自己的代码中,从而保护应用程序避免被过多的请求打垮。另外,该库还支持自定义规则和策略,使得开发人员可以根据自己的业务需求自定义限流规则和处理逻辑,从而实现更加灵活的限流方案。

DotNetRateLimiter库是.NET Core开发中非常实用的一个限流工具,可以帮助开发人员避免因过多的请求而导致的应用程序崩溃和性能问题。

ActionFilters官网:https://github.com/sa-es-ir/DotNet.RateLimit

🚀一、DotNetRateLimiter

🔎1.安装包

代码语言:javascript
代码运行次数:0
运行
复制
DotNetRateLimiter

🔎2.注入和配置

appsettings.json添加如下配置:

代码语言:javascript
代码运行次数:0
运行
复制
"RateLimitOption": {
  "EnableRateLimit": true, //Optional: if set false rate limit will be disabled, default is true
  "HttpStatusCode": 429, //Optional: default is 429
  "ErrorMessage": "Rate limit Exceeded", //Optional: default is Rate limit Exceeded
  "IpHeaderName": "X-Forwarded-For" //Optional: header name for get Ip address, default is X-Forwarded-For
  "RedisConnection": "127.0.0.1:6379", //Optional
  "IpWhiteList": ["::1"], //Optional
  "ClientIdentifier": "X-Client-Id" Optional: for getting client id from request header if this present the rate limit will not use IP for limit requests
  "ClientIdentifierWhiteList": ["test-client"] Optional
}

修改 Program.cs, 添加限流服务

代码语言:javascript
代码运行次数:0
运行
复制
builder.Services.AddRateLimitService(builder.Configuration);

🔎3.使用

🦋3.1 基本使用
代码语言:javascript
代码运行次数:0
运行
复制
[HttpGet("")]
[RateLimit(PeriodInSec = 60, Limit = 3)]
public IEnumerable<WeatherForecast> Get()
{
    return Enumerable.Range(1, 5).Select(index => new WeatherForecast
    {
        Date = DateTime.Now.AddDays(index),
        TemperatureC = Random.Shared.Next(-20, 55),
        Summary = Summaries[Random.Shared.Next(Summaries.Length)]
    })
        .ToArray();
}

DotNetRateLimiter中的PeriodInSec和Limit参数是限流策略的两个重要参数,具体介绍如下:

  1. PeriodInSec参数:表示限流周期。例如,PeriodInSec = 60表示对该接口进行60秒限流,即该接口在60秒内被调用的次数不能超过我们指定的上限。
  2. Limit参数:表示限流的上限。例如,Limit = 10表示该接口在限流周期内最多能够被调用10次。

PeriodInSec和Limit参数配合使用,可以精确控制接口的调用频率。我们可以根据系统的负载和业务需求来灵活配置这两个参数,以达到最佳的限流效果。

RateLimit(PeriodInSec = 60, Limit = 3) 这个接口方法每分钟只允许 3 个请求, 如果调用 api 超过 3 次,就会收到 429(请求过多), 我们使用自动化API测试工具进行压力测试,结果如下:

🦋3.2 路由参数

DotNetRateLimiter是一个基于ASP.NET Core的限流框架,提供了一些限流的功能和配置参数,其中包括RouteParams参数。

RouteParams参数是一个字典类型的参数,其中包括了当前请求的路由参数(RouteData)。 当一个请求到达时,DotNetRateLimiter会自动获取当前请求的路由以及路由参数,并将其作为字典参数传递给限流策略。这样可以让开发者在限流策略中自由的使用路由参数进行更加精细的限流。

代码语言:javascript
代码运行次数:0
运行
复制
[HttpGet("by-route/{id}")]
[RateLimit(PeriodInSec = 60, Limit = 3, RouteParams = "id")]
public IEnumerable<WeatherForecast> Get(int id)
{
    return Enumerable.Range(1, 5).Select(index => new WeatherForecast
    {
        Date = DateTime.Now.AddDays(index),
        TemperatureC = Random.Shared.Next(-20, 55),
        Summary = Summaries[Random.Shared.Next(Summaries.Length)]
    })
        .ToArray();
}
🦋3.3 查询参数

DotNetRateLimiter是一个基于.NET的速率限制库,QueryParams参数是指请求中的查询参数。查询参数通常出现在请求URL的问号(?)后面,例如:https://www.example.com/api?id=1234&name=john。在DotNetRateLimiter中,可以通过配置QueryParams参数来仅对特定的查询参数进行速率限制。

代码语言:javascript
代码运行次数:0
运行
复制
[HttpGet("by-query/{id}")]
[RateLimit(PeriodInSec = 60, Limit = 3, RouteParams = "id", QueryParams = "name,family")]
public IEnumerable<WeatherForecast> Get(int id, string name, [FromQuery] List<string> family)
{
    return Enumerable.Range(1, 5).Select(index => new WeatherForecast
    {
        Date = DateTime.Now.AddDays(index),
        TemperatureC = Random.Shared.Next(-20, 55),
        Summary = Summaries[Random.Shared.Next(Summaries.Length)]
    })
    .ToArray();
}
🦋3.4 主体参数

DotNetRateLimiter是一种限制访问频率的工具,可以用于防止恶意攻击或限制API的访问频率。其中BodyParams参数用于指定请求的正文参数,这些参数将被用于计算请求频率。具体来说,BodyParams参数可以用于以下目的:

1.区分不同的API请求:如果API的请求接口相同,但请求正文参数不同,可以将BodyParams参数设置为请求正文参数的组合,以便对不同的请求进行区分和计数。

2.增加计数的细粒度:将BodyParams参数设置为请求正文中需要计入限制次数的参数,可以增加计数的细粒度,从而更准确地限制访问频率。

需要注意的是,BodyParams参数应该是一个字符串列表,每个字符串表示一个请求正文参数的名称。在使用DotNetRateLimiter时,需要根据具体的API和限制策略,选择合适的BodyParams参数来计算请求频率。

代码语言:javascript
代码运行次数:0
运行
复制
[HttpPut]
[RateLimit(PeriodInSec = 60, Limit = 3, BodyParams = "temperatureC")]
public IActionResult Update([FromBody] WeatherForecast weatherForecast)
{
    return Ok();
}
代码语言:javascript
代码运行次数:0
运行
复制
public class WeatherForecast
{
    public DateTime Date { get; set; }

    public int TemperatureC { get; set; }

    public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);

    public string Summary { get; set; }
}
🦋3.5 控制器

DotNetRateLimiter中的Scope参数是用于标识要限流的资源的作用域或范围。它是一个字符串类型的参数,可以是任何合法的字符串。

Scope参数主要用于将不同的限流规则应用于不同的资源或服务。例如,对于一个在线支付系统,可以将不同的支付接口或业务操作(如支付、退款、查询等)定义为不同的作用域,然后针对每个作用域分别设置不同的限流规则。

Scope参数在DotNetRateLimiter中属于必需的参数,如果不设置Scope参数,则无法启用限流功能。

代码语言:javascript
代码运行次数:0
运行
复制
[ApiController]
[Route("rate-limit-on-controller")]
//if set Scope to Controller to rate limit on all actions no matter which actions call
//the default value is Action means this rate limit check for each action separately
[RateLimit(Limit = 3, PeriodInSec = 60, Scope = RateLimitScope.Controller)]
public class RateLimitOnAllController : ControllerBase
{
    private static readonly string[] Summaries = {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    };

    [HttpGet("")]
    [IgnoreRateLimit]//ignore rate limit for this action
    public IEnumerable<WeatherForecast> Get()
    {
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateTime.Now.AddDays(index),
            TemperatureC = Random.Shared.Next(-20, 55),
            Summary = Summaries[Random.Shared.Next(Summaries.Length)]
        })
            .ToArray();
    }


    [HttpGet("by-route/{id}")]
    public IEnumerable<WeatherForecast> GetByRoute(int id)
    {
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateTime.Now.AddDays(index),
            TemperatureC = Random.Shared.Next(-20, 55),
            Summary = Summaries[Random.Shared.Next(Summaries.Length)]
        })
            .ToArray();
    }

    [HttpGet("by-query/{id}")]
    public IEnumerable<WeatherForecast> GetByQuery(int id, string name, [FromQuery] List<string> family)
    {
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateTime.Now.AddDays(index),
            TemperatureC = Random.Shared.Next(-20, 55),
            Summary = Summaries[Random.Shared.Next(Summaries.Length)]
        })
        .ToArray();
    }



    [HttpPut]
    public IActionResult Update(WeatherForecast weatherForecast)
    {
        return Ok();
    }
}

🚀感谢:给读者的一封信

亲爱的读者,

我在这篇文章中投入了大量的心血和时间,希望为您提供有价值的内容。这篇文章包含了深入的研究和个人经验,我相信这些信息对您非常有帮助。

如果您觉得这篇文章对您有所帮助,我诚恳地请求您考虑赞赏1元钱的支持。这个金额不会对您的财务状况造成负担,但它会对我继续创作高质量的内容产生积极的影响。

我之所以写这篇文章,是因为我热爱分享有用的知识和见解。您的支持将帮助我继续这个使命,也鼓励我花更多的时间和精力创作更多有价值的内容。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-09-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 🚀前言
  • 🚀一、DotNetRateLimiter
    • 🔎1.安装包
    • 🔎2.注入和配置
    • 🔎3.使用
      • 🦋3.1 基本使用
      • 🦋3.2 路由参数
      • 🦋3.3 查询参数
      • 🦋3.4 主体参数
      • 🦋3.5 控制器
  • 🚀感谢:给读者的一封信
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档