如何在ASP.NET Framework API中实现接口限流?
ASP.NET Framework API 限流实现方案(每分钟最多60次调用)
针对ASP.NET Framework API,以下两种方案可以实现你需要的限流功能:
方式一:自定义ActionFilterAttribute(轻量自定义实现)
这种方式无需依赖第三方库,直接通过过滤器结合内存缓存实现基础限流逻辑,适合简单场景。
1. 创建限流过滤器类
using System; using System.Web.Mvc; using System.Runtime.Caching; public class RateLimitAttribute : ActionFilterAttribute { // 限流规则:每分钟最多60次调用 private const int MaxRequestsPerMinute = 60; private const string CacheKeyPrefix = "RateLimit_"; public override void OnActionExecuting(ActionExecutingContext filterContext) { var clientIp = filterContext.HttpContext.Request.UserHostAddress; var cacheKey = $"{CacheKeyPrefix}{clientIp}"; var cacheItem = MemoryCache.Default.Get(cacheKey) as Tuple<int, DateTime>; if (cacheItem == null) { // 首次调用,初始化缓存项 MemoryCache.Default.Add( cacheKey, Tuple.Create(1, DateTime.Now), DateTime.Now.AddMinutes(1)); } else { var currentCount = cacheItem.Item1; var windowStartTime = cacheItem.Item2; if (DateTime.Now.Subtract(windowStartTime).TotalMinutes < 1) { if (currentCount >= MaxRequestsPerMinute) { // 触发限流,返回429状态码 filterContext.Result = new HttpStatusCodeResult(429, "Too Many Requests - 每分钟最多允许60次调用"); return; } // 更新调用计数 MemoryCache.Default.Set( cacheKey, Tuple.Create(currentCount + 1, windowStartTime), DateTime.Now.AddMinutes(1)); } else { // 时间窗口过期,重置计数 MemoryCache.Default.Set( cacheKey, Tuple.Create(1, DateTime.Now), DateTime.Now.AddMinutes(1)); } } base.OnActionExecuting(filterContext); } }
2. 应用过滤器
- 全局应用(所有API控制器生效):在
Global.asax.cs的Application_Start方法中添加:protected void Application_Start() { // 其他初始化代码 GlobalFilters.Filters.Add(new RateLimitAttribute()); } - 单个控制器/Action应用:直接在目标控制器或Action上标记特性:
[RateLimit] public class ApiController : Controller { public JsonResult GetData() { return Json(new { status = "success", data = "example" }, JsonRequestBehavior.AllowGet); } }
方式二:使用第三方库(成熟方案)
如果需要更复杂的限流规则(如多时间窗口、分布式场景支持),可以使用AspNetRateLimit.NetFramework库,它是适配ASP.NET Framework的限流组件。
1. 安装NuGet包
在Package Manager Console中执行:
Install-Package AspNetRateLimit.NetFramework
2. 配置限流规则(Web.config)
添加配置节和限流规则:
<configSections> <section name="clientRateLimit" type="AspNetRateLimit.ClientRateLimitConfiguration, AspNetRateLimit.NetFramework" /> </configSections> <clientRateLimit> <generalRules> <!-- 全局规则:每分钟最多60次调用 --> <add endpoint="*" period="1m" limit="60" /> </generalRules> </clientRateLimit>
3. 注册限流中间件(Global.asax.cs)
using AspNetRateLimit; using System.Web.Http; protected void Application_Start() { // 加载限流配置 var rateLimitConfig = new ClientRateLimitConfiguration(); rateLimitConfig.LoadFromConfig(System.Configuration.ConfigurationManager.GetSection("clientRateLimit")); // 注册限流处理器 GlobalConfiguration.Configuration.MessageHandlers.Add(new ClientRateLimitHandler(rateLimitConfig)); // 其他Web API初始化代码 GlobalConfiguration.Configure(WebApiConfig.Register); }
注意事项
- 上述内存缓存方案仅适用于单实例部署,如果是多服务器分布式场景,需要替换为分布式缓存(如Redis)来存储调用计数。
- 自定义过滤器可以灵活扩展规则,比如按用户ID、API密钥等维度限流,只需修改
cacheKey的生成逻辑即可。
内容的提问来源于stack exchange,提问作者Rikudou En Sof
相关产品推荐
相关产品推荐

