ASP.NET Core 中的速率限制中间件的使用
简介
在ASP.NET Core中,速率限制中间件是用来控制客户端对Web API或MVC应用程序发出请求的速率,以防止服务器过载和提高安全性。
下面是 AddRateLimiter 的一些基本用法:
1. 注册服务
在 Startup.cs 或 Program.cs 中,需要注册 AddRateLimiter 服务。这可以通过以下代码完成:
builder.Services.AddRateLimiter(options =>
{
// 配置速率限制选项
});
2. 添加速率限制策略
可以添加不同类型的速率限制策略, 包括固定窗口、滑动窗口、令牌桶和并发限制。
固定窗口限制器(Fixed Window Limiter)
固定窗口限制器使用固定的时间窗口来限制请求。当时间窗口到期后,会开始一个新的时间窗口,并重置请求限制。例如,可以设置一个策略,允许每个12秒的时间窗口内最多4个请求。
builder.Services.AddRateLimiter(options =>
{
options.AddFixedWindowLimiter("fixed", opt =>
{
opt.Window = TimeSpan.FromMinutes(1); // 时间窗口
opt.PermitLimit = 3; // 在时间窗口内允许的最大请求数
opt.QueueProcessingOrder = QueueProcessingOrder.OldestFirst; // 请求处理顺序
opt.QueueLimit = 2; // 队列中允许的最大请求数
});
});
app.UseRateLimiter();
即固定时间请求的次数,超过次数就会限流,下一个窗口时间将次数重置
经过测试,多余的请求还是会等待
滑动窗口限制器(Sliding Window Limiter)
滑动窗口算法:
- 与固定窗口限制器类似,但为每个窗口添加了段。 窗口在每个段间隔滑动一段。 段间隔的计算方式是:(窗口时间)/(每个窗口的段数)。
- 将窗口的请求数限制为 permitLimit 个请求。
- 每个时间窗口划分为一个窗口 n 个段。
- 从倒退一个窗口的过期时间段(当前段之前的 n 个段)获取的请求会添加到当前的段。 我们将倒退一个窗口最近过期时间段称为“过期的段”。
请考虑下表,其中显示了一个滑动窗口限制器,该限制器的窗口为 30 秒、每个窗口有三个段,且请求数限制为 100 个:
- 第一行和第一列显示时间段。
- 第二行显示剩余的可用请求数。 其余请求数的计算方式为可用请求数减去处理的请求数和回收的请求数。
- 每次的请求数沿着蓝色对角线移动。
- 从时间 30 开始,从过期时间段获得的请求会再次添加到请求数限制中,如红色线条所示。

下表换了一种格式来显示上图中的数据。 “可用”列显示上一个段中可用的请求数(来自上一个行中的“结转”)。 第一行显示有 100 个可用请求,因为没有上一个段。
| 时间 | 可用 | 获取的请求数 | 从过期段回收的请求数 | 结存请求数 |
|---|---|---|---|---|
| 0 | 100 | 20 | 0 | 80 |
| 10 | 80 | 30 | 0 | 50 |
| 20 | 50 | 40 | 0 | 10 |
| 30 | 10 | 30 | 20 | 0 |
| 40 | 0 | 10 | 30 | 20 |
| 50 | 20 | 10 | 40 | 50 |
| 60 | 50 | 35 | 30 | 45 |
services.AddRateLimiter(options =>
{
options.AddSlidingWindowLimiter("sliding", opt =>
{
opt.Window = TimeSpan.FromMinutes(1); // 总窗口时间为1分钟
opt.SegmentsPerWindow = 6; // 将1分钟的窗口分为6个段,即每10秒一个段
opt.PermitLimit = 10; // 整个窗口时间内允许的最大请求数
});
});
令牌桶限制器(Token Bucket Limiter)
令牌桶限制器维护一个滚动累积的使用预算,作为一个令牌的余额。它以一定的速率添加令牌,当服务请求发生时,服务尝试提取一个令牌(减少令牌计数)来满足请求。如果没有令牌,服务就达到了限制,响应被阻塞。
services.AddRateLimiter(configureOptions =>
{
configureOptions.AddTokenBucketLimiter("token-bucket", options =>
{
options.TokenLimit = 100; // 桶的容量
options.ReplenishmentPeriod = TimeSpan.FromSeconds(10); // 补充周期,即每10秒补充一次令牌
options.TokensPerPeriod = 10; // 每个周期补充的令牌数
options.AutoReplenishment = true; // 是否自动补充令牌
options.QueueProcessingOrder = QueueProcessingOrder.OldestFirst; // 队列处理顺序
options.QueueLimit = 10; // 请求队列长度限制
});
});
并发限制器(Concurrency Limiter)
并发限制器是最简单的速率限制形式。它不关注时间,只关注并发请求的数量。
services.AddRateLimiter(options =>
{
options.AddConcurrencyLimiter("concurrency", options =>
{
options.PermitLimit = 1; // 最大并发请求数
options.QueueProcessingOrder = QueueProcessingOrder.OldestFirst; // 队列处理顺序
options.QueueLimit = 10; // 请求队列长度限制
});
});
3. 使用中间件
在 Configure 方法或 Program.cs 中,需要使用 UseRateLimiter 中间件:
app.UseRateLimiter();
4. 应用速率限制策略
可以全局应用速率限制策略,或者将其应用于特定的控制器或动作:
全局配置
app.MapControllers().RequireRateLimiting("fixed");
应用于特定的控制器
[EnableRateLimiting("fixed")]
public class RateLimitTestController : ControllerBase
{
// 控制器动作
}
应用于特定的动作
[EnableRateLimiting("fixed")]
public async Task<IActionResult> Get()
{
// 动作逻辑
}
5. 禁用速率限制
也可以选择禁用速率限制,无论是在控制器级别还是特定动作级别:
禁用控制器级别的速率限制
[DisableRateLimiting]
public class RateLimitTestController : ControllerBase
{
// 控制器动作
}
禁用特定动作的速率限制
[DisableRateLimiting]
public async Task<IActionResult> Get()
{
// 动作逻辑
}
自定义响应
当客户端超出速率限制时,可以自定义响应。例如,可以设置OnRejected回调来自定义响应:
options.OnRejected = (context, token) =>
{
context.HttpContext.Response.StatusCode = StatusCodes.Status429TooManyRequests;
context.HttpContext.Response.Headers["Retry-After"] = "60"; // 建议60秒后重试
context.HttpContext.Response.StatusCode = StatusCodes.Status429TooManyRequests;
context.HttpContext.Response.WriteAsync("Too many requests. Please try again later.", cancellationToken: token);
return Task.CompletedTask;
};

总结
在ASP.NET Core应用程序中实现有效的速率限制策略,以保护的API免受滥用和过载。欢迎关注我的公众号:Net分享
ASP.NET Core 中的速率限制中间件的使用的更多相关文章
- ASP.NET Core 中的那些认证中间件及一些重要知识点
前言 在读这篇文章之间,建议先看一下我的 ASP.NET Core 之 Identity 入门系列(一,二,三)奠定一下基础. 有关于 Authentication 的知识太广,所以本篇介绍几个在 A ...
- [转]ASP.NET Core 中的那些认证中间件及一些重要知识点
本文转自:http://www.qingruanit.net/c_all/article_6645.html 在读这篇文章之间,建议先看一下我的 ASP.NET Core 之 Identity 入门系 ...
- 在ASP.NET Core中编写合格的中间件
这篇文章探讨了让不同的请求去使用不同的中间件,那么我们应该如何配置ASP.NET Core中间件?其实中间件只是在ASP.NET Core中处理Web请求的管道.所有ASP.NET Core应用程序至 ...
- ASP.NET Core 中基于工厂的中间件激活
IMiddlewareFactory/IMiddleware 是中间件激活的扩展点. UseMiddleware 扩展方法检查中间件的已注册类型是否实现 IMiddleware. 如果是,则使用在容器 ...
- [译]在Asp.Net Core 中使用外部登陆(google、微博...)
原文出自Rui Figueiredo的博文<External Login Providers in ASP.NET Core> 摘要:本文主要介绍了使用外部登陆提供程序登陆的流程,以及身份 ...
- ASP.NET Core中如果Response.HasStarted已经为true,就不能更改Response.Cookies和Response.Headers等属性的值了
最近我在ASP.NET Core中做了一个中间件CustomizedMiddleware,要说该中间件的功能也很简单,其实就是往HttpResponse中添加一个Cookie而已,但是我将添加Cook ...
- 【译】在Asp.Net Core 中使用外部登陆(google、微博...)
原文出自Rui Figueiredo的博文<External Login Providers in ASP.NET Core> (本文很长) 摘要:本文主要介绍了使用外部登陆提供程序登陆的 ...
- 在ASP.NET Core 中使用Cookie中间件
在ASP.NET Core 中使用Cookie中间件 ASP.NET Core 提供了Cookie中间件来序列化用户主题到一个加密的Cookie中并且在后来的请求中校验这个Cookie,再现用户并且分 ...
- ASP.NET Core中使用GraphQL - 第二章 中间件
前文:ASP.NET Core中使用GraphQL - 第一章 Hello World 中间件 如果你熟悉ASP.NET Core的中间件,你可能会注意到之前的博客中我们已经使用了一个中间件, app ...
- 在Asp.Net Core中使用中间件保护非公开文件
在企业开发中,我们经常会遇到由用户上传文件的场景,比如某OA系统中,由用户填写某表单并上传身份证,由身份管理员审查,超级管理员可以查看. 就这样一个场景,用户上传的文件只能有三种人看得见(能够访问) ...
随机推荐
- mysql基础-事务
本篇章为初步了解mysql数据事务控制问题,事务作为MySQL的基础篇章是至关重要的一部分内容! 事务 1.事务简介 事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一 ...
- 用easyVget下载B站油管视频
B站油管等视频平台简直就是无所不有的宝库,动漫.番剧.纪录片.科普,更有海量的学习资源,可以极大地满足你的视觉欲和求知欲. 作为一只视频仓鼠,我热衷于下载自己感兴趣的视频到本地,不用担心视频被和谐.不 ...
- Java面试真题之中级进阶(线程,进程,序列化,IO流,NIO)
前言 本来想着给自己放松一下,刷刷博客,慕然回首,线程.程序.进程?Java 序列化?Java 中 IO 流? Java IO与 NIO的区别(补充)?似乎有点模糊了,那就大概看一下Java基础面试题 ...
- 全网最适合入门的面向对象编程教程:58 Python字符串与序列化-序列化Web对象的定义与实现
全网最适合入门的面向对象编程教程:58 Python 字符串与序列化-序列化 Web 对象的定义与实现 摘要: 如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML\YAM ...
- 本文是第一篇在GitHub仓库中撰写的.md格式的blog文件
正文内容: 具体内容,只是未来测试,给出福利: 模板格式: title: 博文标题 description: 博文摘要 #多个标签请使用英文逗号分隔或使用数组语法 tags: 标签1, 标签2 #多个 ...
- Codeforces 909 A-F
CF909 题解 题目链接 A B C D E F 难度:红 黄 绿 蓝 绿 紫 题解 A 题目翻译:给定两个字符串,求字典序最小的"两字符串非空前缀拼接形成的字符串". 算法标签 ...
- OSG开发笔记(三十一):OSG中LOD层次细节模型介绍和使用
前言 模型较大的时候,出现卡顿,那么使用LOD(细节层次)进行层次细节调整,可以让原本卡顿的模型变得不卡顿. 本就是LOD介绍. Demo LOD 概述 LOD也称为层次细节模 ...
- oracle查询是否锁表以及解锁语句
--锁表语句 SELECT b.owner, b.object_name, a.session_id, a.locked_mode FROM v$locked_object a, dba_object ...
- python列表自动扩容机制
问题引入:在对比列表与元组的优缺点时,百度答案为:列表是可变的,可以随时进行增加.修改.删除操作,可以进行动态扩容,动态扩容是以牺牲性能损耗的为代价的,于是我搜索了一下列表的动态扩容 当在创建一个列表 ...
- Tensorflow/Keras、Pytorch 杂记
Tensorflow/Keras 直接从文件生成图片数据 ImageDataGenerator,循环生成图片,在重复生成图片之前,会把所有图片都遍历一遍.而且如果图片总量不是生成批量的倍数的话,在生成 ...