Asp.NET Core 限流控制
yuyutoo 2024-12-03 19:36 1 浏览 0 评论
起因:
近期项目中,提供了一些调用频率较高的api接口,需要保障服务器的稳定运行;需要对提供的接口进行限流控制。避免因客户端频繁的请求导致服务器的压力。
一、AspNetCoreRateLimit 介绍
AspNetCoreRateLimit是一个ASP.NET Core速率限制的解决方案,旨在控制客户端根据IP地址或客户端ID向Web API或MVC应用发出的请求的速率。AspNetCoreRateLimit包含一个IpRateLimitMiddleware和ClientRateLimitMiddleware,每个中间件可以根据不同的场景配置限制允许IP或客户端,自定义这些限制策略,也可以将限制策略应用在每?个API URL或具体的HTTP Method上。
二、AspNetCoreRateLimit使用
由上面介绍可知AspNetCoreRateLimit支持了两种方式:基于客户端IP(IpRateLimitMiddleware)和客户端ID(ClientRateLimitMiddleware)速率限制 接下来就分别说明使用方式
添加Nuget包引用:
Install-Package AspNetCoreRateLimit
- 基于客户端IP速率限制
1、修改Startup.cs中方法:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
//需要从加载配置文件appsettings.json
services.AddOptions();
//需要存储速率限制计算器和ip规则
services.AddMemoryCache();
//从appsettings.json中加载常规配置,IpRateLimiting与配置文件中节点对应
services.Configure<IpRateLimitOptions>(Configuration.GetSection("IpRateLimiting"));
//从appsettings.json中加载Ip规则
services.Configure<IpRateLimitPolicies>(Configuration.GetSection("IpRateLimitPolicies"));
//注入计数器和规则存储
services.AddSingleton<IIpPolicyStore, MemoryCacheIpPolicyStore>();
services.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>();
services.AddControllers();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
//配置(解析器、计数器密钥生成器)
services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();
//Other Code
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//Other Code
app.UseRouting();
app.UseAuthorization();
//启用客户端IP限制速率
app.UseIpRateLimiting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
2、在appsettings.json中添加通用配置项节点:(IpRateLimiting节点与Startup中取的节点对应)
"IpRateLimiting": {
//false,则全局将应用限制,并且仅应用具有作为端点的规则*。例如,如果您设置每秒5次调用的限制,则对任何端点的任何HTTP调用都将计入该限制
//true, 则限制将应用于每个端点,如{HTTP_Verb}{PATH}。例如,如果您为*:/api/values客户端设置每秒5个呼叫的限制,
"EnableEndpointRateLimiting": false,
//false,拒绝的API调用不会添加到调用次数计数器上;如 客户端每秒发出3个请求并且您设置了每秒一个调用的限制,则每分钟或每天计数器等其他限制将仅记录第一个调用,即成功的API调用。如果您希望被拒绝的API调用计入其他时间的显示(分钟,小时等)
//,则必须设置StackBlockedRequests为true。
"StackBlockedRequests": false,
//Kestrel 服务器背后是一个反向代理,如果你的代理服务器使用不同的页眉然后提取客户端IP X-Real-IP使用此选项来设置
"RealIpHeader": "X-Real-IP",
//取白名单的客户端ID。如果此标头中存在客户端ID并且与ClientWhitelist中指定的值匹配,则不应用速率限制。
"ClientIdHeader": "X-ClientId",
//限制状态码
"HttpStatusCode": 429,
////IP白名单:支持Ip v4和v6
//"IpWhitelist": [ "127.0.0.1", "::1/10", "192.168.0.0/24" ],
////端点白名单
//"EndpointWhitelist": [ "get:/api/license", "*:/api/status" ],
////客户端白名单
//"ClientWhitelist": [ "dev-id-1", "dev-id-2" ],
//通用规则
"GeneralRules": [
{
//端点路径
"Endpoint": "*",
//时间段,格式:{数字}{单位};可使用单位:s, m, h, d
"Period": "1s",
//限制
"Limit": 2
},
//15分钟只能调用100次
{"Endpoint": "*","Period": "15m","Limit": 100},
//12H只能调用1000
{"Endpoint": "*","Period": "12h","Limit": 1000},
//7天只能调用10000次
{"Endpoint": "*","Period": "7d","Limit": 10000}
]
}
配置节点已添加相应注释信息。
规则设置格式:
端点格式:{HTTP_Verb}:{PATH},您可以使用asterix符号来定位任何HTTP谓词。
期间格式:{INT}{PERIOD_TYPE},您可以使用以下期间类型之一:s, m, h, d。
限制格式:{LONG}
3、特点Ip限制规则设置,在appsettings.json中添加 IP规则配置节点
"IpRateLimitPolicies": {
//ip规则
"IpRules": [
{
//IP
"Ip": "84.247.85.224",
//规则内容
"Rules": [
//1s请求10次
{"Endpoint": "*","Period": "1s","Limit": 10},
//15分钟请求200次
{"Endpoint": "*","Period": "15m","Limit": 200}
]
},
{
//ip支持设置多个
"Ip": "192.168.3.22/25",
"Rules": [
//1秒请求5次
{"Endpoint": "*","Period": "1s","Limit": 5},
//15分钟请求150次
{"Endpoint": "*","Period": "15m","Limit": 150},
//12小时请求500次
{"Endpoint": "*","Period": "12h","Limit": 500}
]
}
]
}
- 基于客户端ID速率限制
1、修改Startup文件:
public void ConfigureServices(IServiceCollection services)
{
//需要从加载配置文件appsettings.json
services.AddOptions();
//需要存储速率限制计算器和ip规则
services.AddMemoryCache();
//从appsettings.json中加载常规配置
services.Configure<ClientRateLimitOptions>(Configuration.GetSection("IPRateLimiting"));
//从appsettings.json中加载客户端规则
services.Configure<ClientRateLimitPolicies>(Configuration.GetSection("ClientRateLimitPolicies"));
//注入计数器和规则存储
services.AddSingleton<IClientPolicyStore, MemoryCacheClientPolicyStore>();
services.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>();
services.AddControllers();
// https://github.com/aspnet/Hosting/issues/793
// the IHttpContextAccessor service is not registered by default.
//注入计数器和规则存储
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
//配置(解析器、计数器密钥生成器)
services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
//启用客户端限制
app.UseClientRateLimiting();
app.UseMvc();
}
2、通用配置采用IP限制相同配置,添加客户端限制配置:
//客户端限制设置
"ClientRateLimitPolicies": {
"ClientRules": [
{
//客户端id
"ClientId": "client-id-1",
"Rules": [
{"Endpoint": "*","Period": "1s","Limit": 10},
{"Endpoint": "*","Period": "15m","Limit": 200}
]
},
{
"ClientId": "client-id-2",
"Rules": [
{"Endpoint": "*","Period": "1s","Limit": 5},
{"Endpoint": "*","Period": "15m","Limit": 150},
{"Endpoint": "*","Period": "12h","Limit": 500}
]
}
]
}
3、调用结果:
设置规则:1s只能调用一次:首次调用
调用第二次:自定义返回内容
三、其他
- 运行时更新速率限制
添加IpRateLimitController控制器:
/// <summary>
/// IP限制控制器
/// </summary>
[Route("api/[controller]")]
[ApiController]
public class IpRateLimitController : ControllerBase
{
private readonly IpRateLimitOptions _options;
private readonly IIpPolicyStore _ipPolicyStore;
/// <summary>
///
/// </summary>
/// <param name="optionsAccessor"></param>
/// <param name="ipPolicyStore"></param>
public IpRateLimitController(IOptions<IpRateLimitOptions> optionsAccessor, IIpPolicyStore ipPolicyStore)
{
_options = optionsAccessor.Value;
_ipPolicyStore = ipPolicyStore;
}
/// <summary>
/// 获取限制规则
/// </summary>
/// <returns></returns>
[HttpGet]
public async Task<IpRateLimitPolicies> Get()
{
return await _ipPolicyStore.GetAsync(_options.IpPolicyPrefix);
}
/// <summary>
///
/// </summary>
[HttpPost]
public async Task Post(IpRateLimitPolicy ipRate)
{
var pol = await _ipPolicyStore.GetAsync(_options.IpPolicyPrefix);
if (ipRate != null)
{
pol.IpRules.Add(ipRate);
await _ipPolicyStore.SetAsync(_options.IpPolicyPrefix, pol);
}
}
}
- 分布式部署时,需要将速率限制计算器和ip规则存储到分布式缓存中如Redis修改注入对象
// inject counter and rules distributed cache stores
services.AddSingleton<IClientPolicyStore, DistributedCacheClientPolicyStore>();
services.AddSingleton<IRateLimitCounterStore,DistributedCacheRateLimitCounterStore>();
- 添加Nuget包 Microsoft.Extensions.Caching.StackExchangeRedis 在Startup中设置Redis连接
services.AddStackExchangeRedisCache(options =>
{
options.ConfigurationOptions = new ConfigurationOptions
{
//silently retry in the background if the Redis connection is temporarily down
AbortOnConnectFail = false
};
options.Configuration = "localhost:6379";
options.InstanceName = "AspNetRateLimit";
});
- 限制时自定义相应结果://请求返回 "QuotaExceededResponse": { "Content": "{{\"code\":429,\"msg\":\"Visit too frequently, please try again later\",\"data\":null}}", "ContentType": "application/json;utf-8", "StatusCode": 429 },
调用时返回结果:
相关推荐
- TCP协议原理,有这一篇就够了
-
先亮出这篇文章的思维导图:TCP作为传输层的协议,是一个软件工程师素养的体现,也是面试中经常被问到的知识点。在此,我将TCP核心的一些问题梳理了一下,希望能帮到各位。001.能不能说一说TC...
- Win10专业版无线网络老是掉线的问题
-
有一位电脑基地的用户,使用...
- 学习计算机网络需要掌握以下几方面基础知识
-
计算机基础知识操作系统:了解常见操作系统(如Windows、Linux)的基本操作和网络配置,例如如何设置IP地址、子网掩码、网关和DNS服务器等,以及如何通过命令行工具(如ping、tr...
- 网络工程师的圣经!世界级网工手绘268张图让TCP/IP直接通俗易懂
-
要把知识通俗地讲明白,真的不容易。——读者说TCP/IP从字面意义上讲,有人可能会认为TCP/IP是指TCP和IP两种协议。实际生活当中有时候也确实就是这两种协议。然而在很多情况下,它只是...
- 三分钟了解通信知识TCP与IP协议(含“通信技术”资料分享)
-
TCP/IPTCP/IP分层模型①应用层...
- 网闸与防火墙:网络安全设备的差异与应用
-
在网络安全领域,网闸(安全隔离网闸,GAP)和防火墙(Firewall)是两类重要的防护设备。尽管它们都服务于网络安全防护,但在设计理念、技术原理、安全效能及适用场景等方面存在显著差异,以下从五个维度...
- S7-300的TCP/IP通信
-
一、首先在项目中创建2个S7-300的站点;二、硬件组态中,设置合适的TCP/IP地址,在同一网段内;...
- 西门子S7-1500 PLC的 MODBUS TCP通信
-
MODBUSTCP使MODBUS_RTU协议运行于以太网,MODBUSTCP使用TCP/IP和以太网在站点间传送MODBUS报文,MODBUSTCP结合了以太网物理网络和网络标准TC...
- 系统规划与管理师新版备考必备:第7章考点思维导图解析
-
备考系统规划与管理师的小伙伴们,福利又来啦!今天为大家带来《系统规划与管理师(第2版)》第7章考点的思维导图,助你高效梳理重点,让备考更有方向!...
- TCP/IP、Http、Socket 有何区别与联系?
-
HTTP协议对应于应用层,Socket则是对TCP/IP协议的封装和应用(程序员层面上)。HTTP是应用层协议,主要解决如何包装数据。而我们平时说的最多的Socket是什么呢?实际上...
- 西门子PLC串口协议与以太网通信协议对比
-
西门子plc品牌众多,通信协议的类型就更多了,具体可分为串口协议和以太网通信协议两大类。...
- 网络编程懒人入门(十三):一泡尿的时间,快速搞懂TCP和UDP的区别
-
本文引用了作者Fundebug的“一文搞懂TCP与UDP的区别”一文的内容,感谢无私分享。1、引言...
- 程序员必备的学习笔记《TCP/IP详解(一)》
-
为什么会有TCP/IP协议在世界上各地,各种各样的电脑运行着各自不同的操作系统为大家服务,这些电脑在表达同一种信息的时候所使用的方法是千差万别。就好像圣经中上帝打乱了各地人的口音,让他们无法合作一样...
- 一文读懂TCP/IP协议工作原理和工作流程
-
简述本文主要介绍TCP/IP协议工作原理和工作流程。含义TCP/IP协议,英文全称TransmissionControlProtocol/InternetProtocol,包含了一系列构成互联网...
- 如何在 Windows 10 和 Windows 11 上重置 TCP/IP 堆栈
-
传输控制协议/Internet协议,通常称为TCP/IP,是您的WindowsPC如何与Internet上的其他设备进行通信的关键部分。但是当事情出错时会发生什么?你如何解决它?幸运的...
你 发表评论:
欢迎- 一周热门
-
-
前端面试:iframe 的优缺点? iframe有那些缺点
-
带斜线的表头制作好了,如何填充内容?这几种方法你更喜欢哪个?
-
漫学笔记之PHP.ini常用的配置信息
-
其实模版网站在开发工作中很重要,推荐几个参考站给大家
-
推荐7个模板代码和其他游戏源码下载的网址
-
[干货] JAVA - JVM - 2 内存两分 [干货]+java+-+jvm+-+2+内存两分吗
-
正在学习使用python搭建自动化测试框架?这个系统包你可能会用到
-
织梦(Dedecms)建站教程 织梦建站详细步骤
-
【开源分享】2024PHP在线客服系统源码(搭建教程+终身使用)
-
2024PHP在线客服系统源码+完全开源 带详细搭建教程
-
- 最近发表
- 标签列表
-
- mybatis plus (70)
- scheduledtask (71)
- css滚动条 (60)
- java学生成绩管理系统 (59)
- 结构体数组 (69)
- databasemetadata (64)
- javastatic (68)
- jsp实用教程 (53)
- fontawesome (57)
- widget开发 (57)
- vb net教程 (62)
- hibernate 教程 (63)
- case语句 (57)
- svn连接 (74)
- directoryindex (69)
- session timeout (58)
- textbox换行 (67)
- extension_dir (64)
- linearlayout (58)
- vba高级教程 (75)
- iframe用法 (58)
- sqlparameter (59)
- trim函数 (59)
- flex布局 (63)
- contextloaderlistener (56)