Azure Web App上.NET Core 1.0 Web API并发请求IP限制求助
解决.NET Core 1.0 Web API的IP并发请求限制问题
嗨,我来帮你搞定这个问题!针对你用.NET Core 1.0(1.0.5)开发、部署在Azure Web App上的API端点,遇到并发调用导致CPU/DTU飙满的情况,我整理了几个适合你当前版本的IP并发限制方案,咱们一步步来:
方案一:自定义IP并发限制中间件(推荐,可控性强)
因为.NET Core 1.0没有内置的并发限制中间件,咱们自己写一个最靠谱,能精准控制每个IP同时处理的请求数。
1. 创建中间件类
这个类会用线程安全的字典跟踪每个IP的当前并发请求数,请求开始时增加计数,结束时减少,超过限制就返回429错误:
using System.Collections.Concurrent; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; public class IpConcurrentLimitMiddleware { private readonly RequestDelegate _next; private readonly int _maxConcurrentRequests; private readonly ConcurrentDictionary<string, int> _ipRequestCounts = new ConcurrentDictionary<string, int>(); public IpConcurrentLimitMiddleware(RequestDelegate next, int maxConcurrentRequests) { _next = next; _maxConcurrentRequests = maxConcurrentRequests; } public async Task Invoke(HttpContext context) { var clientIp = context.Connection.RemoteIpAddress.ToString(); // 尝试初始化IP计数,或者检查当前计数是否超限 if (!_ipRequestCounts.TryAdd(clientIp, 1)) { if (_ipRequestCounts.TryGetValue(clientIp, out int currentCount) && currentCount >= _maxConcurrentRequests) { context.Response.StatusCode = StatusCodes.Status429TooManyRequests; await context.Response.WriteAsync("Too many concurrent requests from your IP."); return; } _ipRequestCounts.TryUpdate(clientIp, currentCount + 1, currentCount); } try { // 继续处理请求 await _next(context); } finally { // 请求结束后减少计数,清理无请求的IP条目 if (_ipRequestCounts.TryGetValue(clientIp, out int count)) { if (count == 1) { _ipRequestCounts.TryRemove(clientIp, out _); } else { _ipRequestCounts.TryUpdate(clientIp, count - 1, count); } } } } }
2. 注册中间件并指定目标端点
在Startup.cs的Configure方法里,咱们只把这个中间件应用到需要限制的那个API端点(比如/api/heavy-operation),不会影响其他接口:
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { // 先配置转发头,获取真实客户端IP(Azure Web App有代理,必须加这个!) app.UseForwardedHeaders(); // 其他中间件(比如日志、静态文件等)... // 针对特定端点应用并发限制,这里设置最大并发数为5,你可以根据实际情况调整 app.MapWhen(context => context.Request.Path.StartsWithSegments("/api/heavy-operation"), appBuilder => { appBuilder.UseMiddleware<IpConcurrentLimitMiddleware>(maxConcurrentRequests: 5); appBuilder.UseMvc(); }); // 其他路由的Mvc配置 app.UseMvc(); }
3. 配置获取真实客户端IP
Azure Web App会通过代理转发请求,默认RemoteIpAddress拿到的是代理IP,不是用户真实IP,所以要在ConfigureServices里添加转发头配置:
public void ConfigureServices(IServiceCollection services) { services.AddMvc(); // 配置转发头,获取真实客户端IP services.Configure<ForwardedHeadersOptions>(options => { options.ForwardedHeaders = Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.XForwardedFor | Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.XForwardedProto; // 允许Azure代理的IP,测试阶段可以暂时设为*,生产环境建议添加Azure的官方IP范围 options.AllowedHosts = new[] { "*" }; }); }
方案二:使用第三方库(AspNetCoreRateLimit)
如果不想自己写代码,可以试试兼容.NET Core 1.0的第三方速率限制库,不过它的“并发限制”其实是时间窗口内的请求数限制,不是严格的同时处理数,适合对并发要求没那么严苛的场景:
1. 安装NuGet包
打开包管理器控制台,执行:
Install-Package AspNetCoreRateLimit -Version 1.1.0
2. 配置服务和中间件
在Startup.cs的ConfigureServices里:
using AspNetCoreRateLimit; using System.Collections.Generic; public void ConfigureServices(IServiceCollection services) { services.AddMemoryCache(); services.AddMvc(); // 配置IP速率/并发限制 services.Configure<IpRateLimitOptions>(options => { options.GeneralRules = new List<RateLimitRule> { new RateLimitRule { Endpoint = "/api/heavy-operation", Limit = 5, // 1秒内允许的请求数(近似并发) Period = "1s" } }; }); services.AddSingleton<IIpPolicyStore, MemoryCacheIpPolicyStore>(); services.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>(); services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>(); }
在Configure方法里:
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseForwardedHeaders(); app.UseIpRateLimiting(); app.UseMvc(); }
测试与验证
配置完成后,你可以用Postman批量请求、Apache Bench(ab命令)等工具模拟并发调用,看看超过限制时是否返回429错误,同时监控Azure Web App的CPU/DTU指标,确认负载是否下降。
内容的提问来源于stack exchange,提问作者Parthi
相关产品推荐
相关产品推荐

