C#调用AspNetCoreRateLimit限流,如果在appsettings.json中设置IpRateLimiting和IpRateLimitPolicies,则在项目启动时从appsettings.json中加载并应用规则,但在运行过程中没有办法调整规则,此时可以使用IpRateLimitOptions和IIpPolicyStore接口获取并调整限流规则,也可以基于这两个接口将限流规则保存到数据库或第三方缓存,或者从数据库或第三方缓存中读取并应用缓存
IpRateLimitOptions接口维护全局行为与通用规则,对应appsettings.json的IpRateLimiting配置,IIpPolicyStore接口维护特定IP或IP段的限流规则,对应appsettings.json的IpRateLimitPolicies配置。IpRateLimitOptions接口继承自RateLimitOptions类,其内的属性与appsettings.json的IpRateLimiting配置属性大致相同,可以参照之前的文章设置参数,而IIpPolicyStore接口继承自IRateLimitStore,需要调用GetAsync获取IpRateLimitPolicies策略对象,调整策略数据后再调用SetAsync保存IpRateLimitPolicies策略对象。

根据参考文献1的示例代码,结合参考文献2及DeepSeek,编写了动态配置的示例代码,经过验证调用AddGeneralRule动态调整通用规则运行正常,但是添加AddIpRule函数添加的特定规则没有生效,经过调试新增的规则已经保存到_ipPolicyStore内,且代码逻辑和参考文献及大模型给出的代码相同,暂时不清楚不生效的原因。
csharp
public class RateLimitController : ControllerBase
{
private readonly IpRateLimitOptions _options;
private readonly IIpPolicyStore _ipPolicyStore;
public RateLimitController(IOptions<IpRateLimitOptions> optionsAccessor, IIpPolicyStore ipPolicyStore)
{
_options = optionsAccessor.Value;
_ipPolicyStore = ipPolicyStore;
}
[HttpGet]
public string GetString(string content)
{
return content;
}
[HttpGet]
public void AddGeneralRule()
{
_options.GeneralRules.Add(new RateLimitRule
{
Endpoint = "*",
Limit = 2,
Period = "30s"
});
if(_options.EndpointWhitelist==null)
{
_options.EndpointWhitelist=new List<string>();
}
_options.EndpointWhitelist.Add("get:/RateLimit/AddIpRule");
}
[HttpGet]
public async Task AddIpRule()
{
var policy = await _ipPolicyStore.GetAsync(_options.IpPolicyPrefix, HttpContext.RequestAborted);
if (policy == null)
{
await _ipPolicyStore.SeedAsync();
policy = _ipPolicyStore.GetAsync(_options.IpPolicyPrefix).Result;
}
policy.IpRules.AddRange(new IpRateLimitPolicy
{
Ip = "::1",
Rules = new List<RateLimitRule>(new RateLimitRule[] {
new RateLimitRule {
Endpoint = "*:/RateLimit/GetString",
Limit = 5,
Period = "30s" },
})
},
new IpRateLimitPolicy
{
Ip = "127.0.0.1",
Rules = new List<RateLimitRule>(new RateLimitRule[] {
new RateLimitRule {
Endpoint = "*:/RateLimit/GetString",
Limit = 5,
Period = "30s" },
})
});
await _ipPolicyStore.SetAsync(_options.IpPolicyPrefix, policy, cancellationToken: HttpContext.RequestAborted).ConfigureAwait(false);
}
}
参考文献:
1\]https://github.com/stefanprodan/AspNetCoreRateLimit \[2\]https://github.com/stefanprodan/AspNetCoreRateLimit/wiki/IpRateLimitMiddleware