速率限制是一种防止操作频率超过既定限制的技术手段,它的主要作用是保护系统资源和服务的稳定性。具体如下:
- 保护系统资源:通过限制客户端在特定时间内可以发起的请求数量,速率限制确保了系统资源不会被过度消耗。这对于维护系统的长期稳定性和可靠性至关重要。
- 防御恶意行为:速率限制能够减缓或阻止恶意用户对系统进行拒绝服务(DoS)攻击,这种攻击通常是通过发送大量请求来耗尽系统资源,导致合法用户无法访问服务。
- 提高服务质量:对于公开的API或Web服务,速率限制可以防止单个用户占用过多资源,从而确保所有用户都能获得公平的服务体验。
- 防止滥用:速率限制可以防止用户进行潜在的滥用行为,如暴力破解密码攻击,通过限制对特定URI的访问频率,可以有效减缓这类攻击的速度和成功率。
- 流量管理:在一些网络设备和软件中,速率限制也被用作流量管理的工具,以确保网络流量的平稳和合理分配。
综上所述,速率限制在现代网络系统中发挥着重要作用,它不仅保护了系统免受过载的风险,还提供了一种机制来平衡和公平地分配资源。
1、引入命名空间。(不用下载其他包,net8自带,net6就需要AspNetCoreRateLimit,现在查看也可以看到还没有net8版本的依赖)
using Microsoft.AspNetCore.RateLimiting;
using System.Threading.RateLimiting;
2、配置文件。
这里我同之前数据库DBS配置一样,使用的数组,方便后续拓展其他类型
/* 速率限制配置 */
"MyRateLimit": [
{
"PolicyName": "fixed", //策略 AddFixedWindowLimiter (目前代码配置也只使用这个)
"PermitLimit": 10, //请求上限
"Window": 1, //每多少秒
"QueueLimit": 2
}
]
3、创建模型
public class MyRateLimitConfig
{
/// <summary>
/// 策略名称
/// </summary>
public string PolicyName { get; set; }
/// <summary>
/// 请求上限
/// </summary>
public int PermitLimit { get; set; }
/// <summary>
/// 每多少秒的值
/// </summary>
public int Window { get; set; }
/// <summary>
/// 最多允许有多少个请求排队等待处理
/// </summary>
public int QueueLimit { get; set; }
/// <summary>
/// 该类在json配置文件中的名称
/// </summary>
public static string MyRateLimit = "MyRateLimit";
}
4、读取配置信息
List<MyRateLimitConfig> myRateLimitList = AppSettings.app<MyRateLimitConfig>(MyRateLimitConfig.MyRateLimit).ToList();
var myRateLimit = myRateLimitList.FirstOrDefault();
5、核心代码
//AddFixedWindowLimiter 方法使用固定的时间窗口来限制请求。 当时间窗口过期时,会启动一个新的时间窗口,并重置请求限制。
builder.Services.AddRateLimiter(_ => _
.AddFixedWindowLimiter(policyName: "fixed", options =>
{
options.PermitLimit = myRateLimit.PermitLimit;
options.Window = TimeSpan.FromSeconds(myRateLimit.Window);
options.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
options.QueueLimit = myRateLimit.QueueLimit;
}));
app.UseRateLimiter();
6、使用
可以使用在控制器上边,也可以加在action接口上。或者默认全部接口都带入
这里我们在接口登录上边使用
/// <summary>
/// 登录
/// </summary>
/// <param name="para">入参</param>
/// <returns></returns>
[ApiVersionCustomRoute("Login", SwaggerDocSettings.ApiVersions.v1)]
[EnableRateLimiting("fixed")] //速率限制特性
[HttpPost]
public async Task<ApiResult> GetUser(LoginUserParameters para)
7、测试
这里我们使用apipost的一键压测功能测试
7.1、不使用:
看下图,我们的所有请求都是可以通过的。
7.2、使用:
看下图。只成功运行了100条数据。这也就是我们前边配置文件中所设置的1秒10条。这里一共10秒,所以也就是10*10 =100。需要更具体的可以在apipost上开启日志记录进行查看。
8、其他
8.1、本文参考官方:ASP.NET Core 中的速率限制中间件 | Microsoft Learn
8.2、这里只使用了其中一种方案,还有几种可以自行拓展。
8.3、之前查询资料的时候也看到了些其他方案,自建限流,使用特性标注 。(主要逻辑就是使用缓存存储ip地址的访问次数,配置文件配置每秒上限)。
9、推荐阅读