何为IpRateLimitMiddleware
IpRateLimitMiddleware(Github: AspNetCoreRateLimit) 是ASPNETCore的一个限流的中间件,用于控制客户端调用API的频次, 如果客户端频繁访问服务器,可以限制它的频率,已降低访问服务器端的压力。或者如果有爬虫在爬取关键数据,也可以限制某个/某些API或者某些IP的每天调取次数, 这样限制他爬取的速度。
首先nuget安装 Install-Package AspNetCoreRateLimit ,在Startup中Code以下代码,添加服务和注入
StartUp.cs代码
public void ConfigureServices(IServiceCollection services)
{
// needed to load configuration from appsettings.json
services.AddOptions();
// needed to store rate limit counters and ip rules
services.AddMemoryCache();
//load general configuration from appsettings.json
services.Configure<IpRateLimitOptions>(Configuration.GetSection("IpRateLimiting"));
//load ip rules from appsettings.json
services.Configure<IpRateLimitPolicies>(Configuration.GetSection("IpRateLimitPolicies"));
// inject counter and rules stores
services.AddSingleton<IIpPolicyStore, MemoryCacheIpPolicyStore>();
services.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>();
// Add framework services.
services.AddMvc();
// https://github.com/aspnet/Hosting/issues/793
// the IHttpContextAccessor service is not registered by default.
// the clientId/clientIp resolvers use it.
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
// configuration (resolvers, counter key builders)
services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseIpRateLimiting();
//if (env.IsDevelopment())
// app.UseDeveloperExceptionPage();
app.UseMvc();
}
IPRateLimiting应该在其他中间件之前注册, 否则API请求计算可能不正确。
如果您对应用程序进行负载平衡,则需要使用IDistributedCache
Redis或SQLServer,以便所有的kestrel实例都具有相同的速率限制存储。您应该像这样注入分布式存储,而不是使用MemoryCache:
配置和一般规则appsettings.json
1 "IpRateLimiting": {
2 "EnableEndpointRateLimiting": false,
3 "StackBlockedRequests": false,
4 "RealIpHeader": "X-Real-IP",
5 "ClientIdHeader": "X-ClientId",
6 "HttpStatusCode": 429,
7 //"IpWhitelist": [ "127.0.0.1", "::1/10", "192.168.0.0/24" ],
8 //"EndpointWhitelist": [ "get:/api/license", "*:/api/status" ],
9 //"ClientWhitelist": [ "dev-id-1", "dev-id-2" ],
10 "GeneralRules": [
11 {
12 "Endpoint": "*",
13 "Period": "1s",
14 "Limit": 1
15 },
16 {
17 "Endpoint": "*",
18 "Period": "15m",
19 "Limit": 100
20 },
21 {
22 "Endpoint": "*",
23 "Period": "12h",
24 "Limit": 1000
25 },
26 {
27 "Endpoint": "*",
28 "Period": "7d",
29 "Limit": 10000
30 }
31 ]
32 }
如果EnableEndpointRateLimiting
设置为false
则全局将应用限制,并且仅应用具有作为端点的规则*
。例如,如果您设置每秒5次调用的限制,则对任何端点的任何HTTP调用都将计入该限制。
如果EnableEndpointRateLimiting
设置为true
,则限制将应用于每个端点,如{HTTP_Verb}{PATH}
。例如,如果您为*:/api/values
客户端设置每秒5个呼叫的限制,则可以GET /api/values
每秒呼叫5次,但也可以呼叫5次PUT /api/values
。
如果StackBlockedRequests
设置为false
,拒绝的API调用不会添加到调用次数计数器上。比如: 如果客户端每秒发出3个请求并且您设置了每秒一个调用的限制,则每分钟或每天计数器等其他限制将仅记录第一个调用,即成功的API调用。如果您希望被拒绝的API调用计入其他时间的显示(分钟,小时等),则必须设置StackBlockedRequests
为true
。
在RealIpHeader
使用时,你的Kestrel 服务器背后是一个反向代理,如果你的代理服务器使用不同的页眉然后提取客户端IP X-Real-IP
使用此选项来设置它。
将ClientIdHeader
被用于提取白名单的客户端ID。如果此标头中存在客户端ID并且与ClientWhitelist中指定的值匹配,则不应用速率限制。
覆盖特定IP appsettings.json的一般规则:
"IpRateLimitPolicies": {
"IpRules": [
{
"Ip": "84.247.85.224",
"Rules": [
{
"Endpoint": "*",
"Period": "1s",
"Limit": 10
},
{
"Endpoint": "*",
"Period": "15m",
"Limit": 200
}
]
},
{
"Ip": "192.168.3.22/25",
"Rules": [
{
"Endpoint": "*",
"Period": "1s",
"Limit": 5
},
{
"Endpoint": "*",
"Period": "15m",
"Limit": 150
},
{
"Endpoint": "*",
"Period": "12h",
"Limit": 500
}
]
}
]
}
IP字段支持IP v4和v6值以及范围,如 "192.168.0.0/24", "fe80::/10" 或 "192.168.0.0-192.168.0.255"。
IpRateLimitMiddleware(Github: AspNetCoreRateLimit) 是ASPNETCore的一个限流的中间件,用于控制客户端调用API的频次, 如果客户端频繁访问服务器,可以限制它的频率,已降低访问服务器端的压力。或者如果有爬虫在爬取关键数据,也可以限制某个/某些API或者某些IP的每天调取次数, 这样限制他爬取的速度。
首先nuget安装 Install-Package AspNetCoreRateLimit ,在Startup中Code以下代码,添加服务和注入
StartUp.cs代码
public void ConfigureServices(IServiceCollection services)
{
// needed to load configuration from appsettings.json
services.AddOptions();
// needed to store rate limit counters and ip rules
services.AddMemoryCache();
//load general configuration from appsettings.json
services.Configure<IpRateLimitOptions>(Configuration.GetSection("IpRateLimiting"));
//load ip rules from appsettings.json
services.Configure<IpRateLimitPolicies>(Configuration.GetSection("IpRateLimitPolicies"));
// inject counter and rules stores
services.AddSingleton<IIpPolicyStore, MemoryCacheIpPolicyStore>();
services.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>();
// Add framework services.
services.AddMvc();
// https://github.com/aspnet/Hosting/issues/793
// the IHttpContextAccessor service is not registered by default.
// the clientId/clientIp resolvers use it.
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
// configuration (resolvers, counter key builders)
services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseIpRateLimiting();
//if (env.IsDevelopment())
// app.UseDeveloperExceptionPage();
app.UseMvc();
}
IPRateLimiting应该在其他中间件之前注册, 否则API请求计算可能不正确。
如果您对应用程序进行负载平衡,则需要使用IDistributedCache
Redis或SQLServer,以便所有的kestrel实例都具有相同的速率限制存储。您应该像这样注入分布式存储,而不是使用MemoryCache:
配置和一般规则appsettings.json
1 "IpRateLimiting": {
2 "EnableEndpointRateLimiting": false,
3 "StackBlockedRequests": false,
4 "RealIpHeader": "X-Real-IP",
5 "ClientIdHeader": "X-ClientId",
6 "HttpStatusCode": 429,
7 //"IpWhitelist": [ "127.0.0.1", "::1/10", "192.168.0.0/24" ],
8 //"EndpointWhitelist": [ "get:/api/license", "*:/api/status" ],
9 //"ClientWhitelist": [ "dev-id-1", "dev-id-2" ],
10 "GeneralRules": [
11 {
12 "Endpoint": "*",
13 "Period": "1s",
14 "Limit": 1
15 },
16 {
17 "Endpoint": "*",
18 "Period": "15m",
19 "Limit": 100
20 },
21 {
22 "Endpoint": "*",
23 "Period": "12h",
24 "Limit": 1000
25 },
26 {
27 "Endpoint": "*",
28 "Period": "7d",
29 "Limit": 10000
30 }
31 ]
32 }
如果EnableEndpointRateLimiting
设置为false
则全局将应用限制,并且仅应用具有作为端点的规则*
。例如,如果您设置每秒5次调用的限制,则对任何端点的任何HTTP调用都将计入该限制。
如果EnableEndpointRateLimiting
设置为true
,则限制将应用于每个端点,如{HTTP_Verb}{PATH}
。例如,如果您为*:/api/values
客户端设置每秒5个呼叫的限制,则可以GET /api/values
每秒呼叫5次,但也可以呼叫5次PUT /api/values
。
如果StackBlockedRequests
设置为false
,拒绝的API调用不会添加到调用次数计数器上。比如: 如果客户端每秒发出3个请求并且您设置了每秒一个调用的限制,则每分钟或每天计数器等其他限制将仅记录第一个调用,即成功的API调用。如果您希望被拒绝的API调用计入其他时间的显示(分钟,小时等),则必须设置StackBlockedRequests
为true
。
在RealIpHeader
使用时,你的Kestrel 服务器背后是一个反向代理,如果你的代理服务器使用不同的页眉然后提取客户端IP X-Real-IP
使用此选项来设置它。
将ClientIdHeader
被用于提取白名单的客户端ID。如果此标头中存在客户端ID并且与ClientWhitelist中指定的值匹配,则不应用速率限制。
覆盖特定IP appsettings.json的一般规则:
"IpRateLimitPolicies": {
"IpRules": [
{
"Ip": "84.247.85.224",
"Rules": [
{
"Endpoint": "*",
"Period": "1s",
"Limit": 10
},
{
"Endpoint": "*",
"Period": "15m",
"Limit": 200
}
]
},
{
"Ip": "192.168.3.22/25",
"Rules": [
{
"Endpoint": "*",
"Period": "1s",
"Limit": 5
},
{
"Endpoint": "*",
"Period": "15m",
"Limit": 150
},
{
"Endpoint": "*",
"Period": "12h",
"Limit": 500
}
]
}
]
}
IP字段支持IP v4和v6值以及范围,如 "192.168.0.0/24", "fe80::/10" 或 "192.168.0.0-192.168.0.255"。