ASP.NET Core 中的速率限制中间件的使用

打印 上一主题 下一主题

主题 858|帖子 858|积分 2574

简介

在ASP.NET Core中,速率限制中间件是用来控制客户端对Web API或MVC应用程序发出哀求的速率,以防止服务器过载和提高安全性。
下面是 AddRateLimiter 的一些基本用法:
1. 注册服务

在 Startup.cs 或 Program.cs 中,需要注册 AddRateLimiter 服务。这可以通过以下代码完成:
  1. builder.Services.AddRateLimiter(options =>
  2. {
  3.     // 配置速率限制选项
  4. });
复制代码
2. 添加速率限制策略

可以添加不同类型的速率限制策略, 包括固定窗口、滑动窗口、令牌桶和并发限制。
固定窗口限制器(Fixed Window Limiter)

固定窗口限制器使用固定的时间窗口来限制哀求。当时间窗口到期后,会开始一个新的时间窗口,并重置哀求限制。例如,可以设置一个策略,允许每个12秒的时间窗口内最多4个哀求。
  1. builder.Services.AddRateLimiter(options =>
  2. {
  3.     options.AddFixedWindowLimiter("fixed", opt =>
  4.     {
  5.         opt.Window = TimeSpan.FromMinutes(1); // 时间窗口
  6.         opt.PermitLimit = 3; // 在时间窗口内允许的最大请求数
  7.         opt.QueueProcessingOrder = QueueProcessingOrder.OldestFirst; // 请求处理顺序
  8.         opt.QueueLimit = 2; // 队列中允许的最大请求数
  9.     });
  10. });
  11. app.UseRateLimiter();
复制代码
即固定时间哀求的次数,超过次数就会限流,下一个窗口时间将次数重置
经过测试,多余的哀求还是会等候
https://www.cnblogs.com/guoxiaotian/p/17834892.html
滑动窗口限制器(Sliding Window Limiter)

滑动窗口算法:

  • 与固定窗口限制器类似,但为每个窗口添加了段。 窗口在每个段隔断滑动一段。 段隔断的计算方式是:(窗口时间)/(每个窗口的段数)。
  • 将窗口的哀求数限制为 permitLimit 个哀求。
  • 每个时间窗口划分为一个窗口 n 个段。
  • 从倒退一个窗口的逾期时间段(当前段之前的 n 个段)获取的哀求会添加到当前的段。 我们将倒退一个窗口近来逾期时间段称为“逾期的段”。
请思量下表,此中显示了一个滑动窗口限制器,该限制器的窗口为 30 秒、每个窗口有三个段,且哀求数限制为 100 个:

  • 第一行和第一列显示时间段。
  • 第二行显示剩余的可用哀求数。 其余哀求数的计算方式为可用哀求数减去处理的哀求数和回收的哀求数。
  • 每次的哀求数沿着蓝色对角线移动。
  • 从时间 30 开始,从逾期时间段获得的哀求会再次添加到哀求数限制中,如赤色线条所示。

下表换了一种格式来显示上图中的数据。 “可用”列显示上一个段中可用的哀求数(来自上一个行中的“结转”)。 第一行显示有 100 个可用哀求,由于没有上一个段。
时间可用获取的哀求数从逾期段回收的哀求数结存哀求数01002008010803005020504001030103020040010302050201040506050353045
  1. services.AddRateLimiter(options =>
  2.     {
  3.         options.AddSlidingWindowLimiter("sliding", opt =>
  4.         {
  5.             opt.Window = TimeSpan.FromMinutes(1); // 总窗口时间为1分钟
  6.             opt.SegmentsPerWindow = 6; // 将1分钟的窗口分为6个段,即每10秒一个段
  7.             opt.PermitLimit = 10; // 整个窗口时间内允许的最大请求数
  8.         });
  9.     });
复制代码
令牌桶限制器(Token Bucket Limiter)

令牌桶限制器维护一个滚动累积的使用预算,作为一个令牌的余额。它以一定的速率添加令牌,当服务哀求发生时,服务尝试提取一个令牌(淘汰令牌计数)来满足哀求。如果没有令牌,服务就达到了限制,响应被阻塞。
  1.     services.AddRateLimiter(configureOptions =>
  2.     {
  3.         configureOptions.AddTokenBucketLimiter("token-bucket", options =>
  4.         {
  5.             options.TokenLimit = 100; // 桶的容量
  6.             options.ReplenishmentPeriod = TimeSpan.FromSeconds(10); // 补充周期,即每10秒补充一次令牌
  7.             options.TokensPerPeriod = 10; // 每个周期补充的令牌数
  8.             options.AutoReplenishment = true; // 是否自动补充令牌
  9.             options.QueueProcessingOrder = QueueProcessingOrder.OldestFirst; // 队列处理顺序
  10.             options.QueueLimit = 10; // 请求队列长度限制
  11.         });
  12.     });
复制代码
并发限制器(Concurrency Limiter)

并发限制器是最简单的速率限制情势。它不关注时间,只关注并发哀求的数目。
  1.     services.AddRateLimiter(options =>
  2.     {
  3.         options.AddConcurrencyLimiter("concurrency", options =>
  4.         {
  5.             options.PermitLimit = 1; // 最大并发请求数
  6.             options.QueueProcessingOrder = QueueProcessingOrder.OldestFirst; // 队列处理顺序
  7.             options.QueueLimit = 10; // 请求队列长度限制
  8.         });
  9.     });
复制代码
3. 使用中间件

在 Configure 方法或 Program.cs 中,需要使用 UseRateLimiter 中间件:
  1. app.UseRateLimiter();
复制代码
4. 应用速率限制策略

可以全局应用速率限制策略,大概将其应用于特定的控制器或动作:
全局配置
  1. app.MapControllers().RequireRateLimiting("fixed");
复制代码
应用于特定的控制器
  1. [EnableRateLimiting("fixed")]
  2. public class RateLimitTestController : ControllerBase
  3. {
  4.     // 控制器动作
  5. }
复制代码
应用于特定的动作
  1. [EnableRateLimiting("fixed")]
  2. public async Task<IActionResult> Get()
  3. {
  4.     // 动作逻辑
  5. }
复制代码
5. 禁用速率限制

也可以选择禁用速率限制,无论是在控制器级别还是特定动作级别:
禁用控制器级别的速率限制
  1. [DisableRateLimiting]
  2. public class RateLimitTestController : ControllerBase
  3. {
  4.     // 控制器动作
  5. }
复制代码
禁用特定动作的速率限制
  1. [DisableRateLimiting]
  2. public async Task<IActionResult> Get()
  3. {
  4.     // 动作逻辑
  5. }
复制代码
自定义响应

当客户端超出速率限制时,可以自定义响应。例如,可以设置OnRejected回调来自定义响应:
  1. options.OnRejected = (context, token) =>
  2. {
  3.     context.HttpContext.Response.StatusCode = StatusCodes.Status429TooManyRequests;
  4.     context.HttpContext.Response.Headers["Retry-After"] = "60"; // 建议60秒后重试
  5.      context.HttpContext.Response.StatusCode = StatusCodes.Status429TooManyRequests;
  6. context.HttpContext.Response.WriteAsync("Too many requests. Please try again later.", cancellationToken: token);
  7.                   
  8.     return Task.CompletedTask;
  9. };
复制代码

总结

在ASP.NET Core应用程序中实现有效的速率限制策略,以保护的API免受滥用和过载。欢迎关注我的公众号:Net分享

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

曂沅仴駦

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表