如何在.NET Core 3.1中实现Azure Function限流?求替代方案
.NET Core 3.1环境下Azure Function限流替代方案
针对你的需求,以下是几种无需依赖Azure API Management或ThrottlingTroll的限流方案,均兼容.NET Core 3.1:
方案一:使用AspNetCoreRateLimit库
这是一个成熟的第三方限流库,支持基于IP、客户端ID的细粒度限流规则,适配.NET Core 3.1环境。
实现步骤:
- 安装NuGet包:
Install-Package AspNetCoreRateLimit - 在
Startup.cs中配置服务:public void ConfigureServices(IServiceCollection services) { // 加载限流配置 services.AddOptions(); services.AddMemoryCache(); services.Configure<IpRateLimitOptions>(Configuration.GetSection("IpRateLimiting")); services.Configure<IpRateLimitPolicies>(Configuration.GetSection("IpRateLimitPolicies")); // 注入限流核心服务 services.AddSingleton<IIpPolicyStore, MemoryCacheIpPolicyStore>(); services.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>(); services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>(); services.AddSingleton<IProcessingStrategy, AsyncKeyLockProcessingStrategy>(); } - 在
Configure方法中注册限流中间件:public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseIpRateLimiting(); // 其他中间件注册逻辑 } - 在
appsettings.json中定义限流规则:"IpRateLimiting": { "EnableEndpointRateLimiting": true, "StackBlockedRequests": false, "RealIpHeader": "X-Real-IP", "ClientIdHeader": "X-ClientId", "HttpStatusCode": 429, "GeneralRules": [ { "Endpoint": "*:/api/*", "Period": "1m", "Limit": 100 } ] }
注意:若Azure Function采用隔离进程模式,需调整中间件注册逻辑,确保其接入Function的请求处理管道。
方案二:自定义限流实现
如果不想引入第三方库,可根据业务场景实现轻量级限流逻辑,支持单实例和多实例场景:
单实例场景(内存存储)
使用ConcurrentDictionary维护请求计数,适合单实例部署的Function:
private static readonly ConcurrentDictionary<string, (int Count, DateTime LastResetTime)> _rateLimits = new(); private const int MaxRequestsPerMinute = 100; [FunctionName("MyRestrictedFunction")] public async Task<IActionResult> Run( [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, ILogger log) { var clientIp = req.HttpContext.Connection.RemoteIpAddress.ToString(); var now = DateTime.UtcNow; // 更新请求计数 _rateLimits.AddOrUpdate(clientIp, _ => (1, now), (_, existing) => { if (now - existing.LastResetTime > TimeSpan.FromMinutes(1)) { return (1, now); } return (existing.Count + 1, existing.LastResetTime); }); var currentState = _rateLimits[clientIp]; if (currentState.Count > MaxRequestsPerMinute) { return new StatusCodeResult(429); } // 执行业务逻辑 return new OkObjectResult("Request processed"); }
多实例场景(Redis分布式存储)
利用Redis的原子命令实现分布式限流,适合多实例部署的Function:
private static readonly ConnectionMultiplexer _redis = ConnectionMultiplexer.Connect("your-redis-connection-string"); private const int MaxRequestsPerMinute = 100; private const int WindowSeconds = 60; [FunctionName("MyDistributedRestrictedFunction")] public async Task<IActionResult> Run( [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, ILogger log) { var clientIp = req.HttpContext.Connection.RemoteIpAddress.ToString(); var rateLimitKey = $"rate-limit:{clientIp}"; var redisDb = _redis.GetDatabase(); // 原子递增计数 var requestCount = await redisDb.StringIncrementAsync(rateLimitKey); // 首次请求时设置过期时间 if (requestCount == 1) { await redisDb.KeyExpireAsync(rateLimitKey, TimeSpan.FromSeconds(WindowSeconds)); } if (requestCount > MaxRequestsPerMinute) { return new StatusCodeResult(429); } // 执行业务逻辑 return new OkObjectResult("Request processed"); }
方案三:平台级限流(App Service计划)
如果无需细粒度的API/客户端限流,可通过调整Azure Function的App Service计划配置来限制整体调用量:
- 调整计划的实例数上限,控制并发处理能力
- 利用App Service的"缩放规则"设置基于CPU/内存的自动缩放,间接控制请求处理量
此方案仅适用于全局限流场景,无法针对特定API或客户端做精准限制。
内容的提问来源于stack exchange,提问作者Jacob Sánche
相关产品推荐
相关产品推荐

