需要安装最新的dll中间件:
1、在项目nutget中找到AspNetCoreRateLimit组件
2、在项目nutget中找到AspNetCoreRateLimit.Redis组件
json配置文件如下(ip限制配置):
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"token": "task123456",
"superToken": "task_admin",
"AllowedHosts": "*",
"IpRateLimiting": {
//false,则全局将应用限制,并且仅应用具有作为端点的规则*。例如,如果您设置每秒5次调用的限制,则对任何端点的任何HTTP调用都将计入该限制
//true, 则限制将应用于每个端点,如{HTTP_Verb}{PATH}。例如,如果您为*:/api/values客户端设置每秒5个呼叫的限制,
"EnableEndpointRateLimiting": true,
//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,
"IpWhitelist": ["127.0.0.1","192.168.0.0/24" ],
//"EndpointWhitelist": [ "delete:/api/values", "*:/api/clients", "*:/api/ClientRateLimit", "*:/api/IpRateLimit", "get:/" ],
//"ClientWhitelist": [ "cl-key-1", "cl-key-2" ],
"QuotaExceededResponse": {
"Content": "{{ \"message\": \"Whoa! Calm down, cowboy!\", \"details\": \"Quota exceeded. Maximum allowed: {0} per {1}. Please try again in {2} second(s).\" }}",
"ContentType": "application/json"
},
"GeneralRules": [
{
"Endpoint": "get:/HealthCheck",
"Period": "10s",
"Limit": 10,
"QuotaExceededResponse": {
"Content": "{{\"code\":403,\"msg\":\"Forbidden!\",\"data\":null}}",
"ContentType": "application/json;utf-8",
"StatusCode": 403
}
}
]
},
"IpRateLimitPolicies": {
"IpRules": [
{
"Ip": "184.47.85.24",
"Rules": [
{
"Endpoint": "*",
"Period": "1s",
"Limit": 10
},
{
"Endpoint": "*",
"Period": "1m",
"Limit": 2
},
{
"Endpoint": "post:/api/values",
"Period": "1m",
"Limit": 5
}
]
},
{
"Ip": "184.27.85.25",
"Rules": [
{
"Endpoint": "*",
"Period": "1s",
"Limit": 10
},
{
"Endpoint": "*",
"Period": "1m",
"Limit": 5
},
{
"Endpoint": "*",
"Period": "1h",
"Limit": 2
}
]
},
{
"Ip": "84.47.8.226",
"Rules": [
{
"Endpoint": "*",
"Period": "1s",
"Limit": 10
},
{
"Endpoint": "*",
"Period": "1m",
"Limit": 5
},
{
"Endpoint": "*",
"Period": "1d",
"Limit": 2
}
]
},
{
"Ip": "64.67.85.81",
"Rules": [
{
"Endpoint": "*",
"Period": "1m",
"Limit": 0
}
]
},
{
"Ip": "94.207.105.202",
"Rules": [
{
"Endpoint": "*",
"Period": "1m",
"Limit": 1,
"MonitorMode": true
}
]
}
]
}
}
#region AspNetCoreRateLimit 代码段是相关的配置文件,切记注意 services.AddRedisRateLimiting();代码放在代码端最后;
public void ConfigureServices(IServiceCollection services)
{
#region AspNetCoreRateLimit
//需要从加载配置文件appsettings.json
services.AddOptions();
//内存
//services.AddMemoryCache();
//redis
var redisOptions = ConfigurationOptions.Parse("127.0.0.1:16001,allowAdmin=true");
services.AddSingleton<IConnectionMultiplexer>(provider => ConnectionMultiplexer.Connect(redisOptions));
//从appsettings.json中加载常规配置
services.Configure<IpRateLimitOptions>(Configuration.GetSection("IpRateLimiting"));
services.Configure<IpRateLimitPolicies>(Configuration.GetSection("IpRateLimitPolicies"));
//从appsettings.json中加载客户端规则
//services.Configure<ClientRateLimitOptions>(Configuration.GetSection("ClientRateLimiting"));
//services.Configure<ClientRateLimitPolicies>(Configuration.GetSection("ClientRateLimitPolicies"));
//4.0后,必须注入处理策略
services.AddSingleton<IProcessingStrategy, AsyncKeyLockProcessingStrategy>();
//注入计数器和规则存储
//内存
//services.AddSingleton<IIpPolicyStore, MemoryCacheIpPolicyStore>();
//services.AddSingleton<IClientPolicyStore, MemoryCacheClientPolicyStore>();
//services.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>();
//redis
services.AddSingleton<IRateLimitCounterStore, DistributedCacheRateLimitCounterStore>();
services.AddSingleton<IIpPolicyStore, DistributedCacheIpPolicyStore>();
services.AddSingleton<IClientPolicyStore, DistributedCacheClientPolicyStore>();
//解析clientid和ip的使用有用,如果默认没有启用,则此处启用
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
// 配置(解析器、计数器密钥生成器)
services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();
//存入到redis 一定放在这个位置
services.AddRedisRateLimiting();
#endregion
//Other Code
services.AddHttpClient();
services.AddControllers()
.AddNewtonsoftJson(op =>
{
op.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver();
op.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
});
services.AddHttpClient();
services.AddHttpContextAccessor();
services.AddSession().AddMemoryCache();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
#region AspNetCoreRateLimit
app.UseIpRateLimiting();
//app.UseClientRateLimiting();
#endregion
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
app.UseStaticFiles();
app.UseAuthentication();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=TaskBackGround}/{action=Index}/{id?}");
});
}
2、net6.0下 AspNetCoreRateLimit5.0、CSRedisCore3.8.670 Caching.CSRedis3.8.670 使用方法(此用法没测试)
using AspNetCoreRateLimit;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Caching.Redis;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
public static class RateLimitServiceCollectionExtensions
{
/// <summary>
/// 添加Ip限流
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
/// <param name="cacheConfig"></param>
public static void AddIpRateLimit(this IServiceCollection services, IConfiguration configuration)
{
#region IP限流
services.Configure<IpRateLimitOptions>(configuration.GetSection("IpRateLimiting"));
services.Configure<IpRateLimitPolicies>(configuration.GetSection("IpRateLimitPolicies"));
if (true)
{
//redis
var redisRateLimit = new CSRedis.CSRedisClient("127.0.0.1:6379,allowAdmin=true");
services.AddSingleton<IDistributedCache>(new CSRedisCache(redisRateLimit));
services.AddDistributedRateLimiting();
}
else
{
//内存
services.AddMemoryCache();
services.AddInMemoryRateLimiting();
}
services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();
#endregion IP限流
}
}
redis会有计数数据: