当前位置: 首页 > news >正文

ASP.NET Core 请求限速的ActionFilter

文章目录

  • 前言
  • 一、实现步骤
    • 1)创建自定义Action Filter
      • 示例1:
      • 示例2:
    • 2)注册服务
    • 3)使用
  • 二、实现说明
  • 总结


前言

以下是一个基于内存缓存实现的自定义限流Action Filter。

一、实现步骤

1)创建自定义Action Filter

示例1:

  1. MyRateLimitAttribute.cs
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.AspNetCore.Mvc.Filters;
    using Microsoft.Extensions.Caching.Memory;public class MyRateLimitAttribute : TypeFilterAttribute{public MyRateLimitAttribute() :base(typeof(MyRateLimitFilter)){}public class MyRateLimitFilter : IAsyncActionFilter{private readonly IMemoryCache _memoryCache;public MyRateLimitFilter(IMemoryCache memoryCache){_memoryCache = memoryCache;}public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next){string ip = context.HttpContext.Connection.RemoteIpAddress.ToString();if (string.IsNullOrEmpty(ip)){context.Result = new BadRequestObjectResult("Invalid Client IP");return;}string cacheKey = $"MyRateLimit_{ip}";_memoryCache.TryGetValue<long?>(cacheKey, out long? lastVisit);if (lastVisit == null || Environment.TickCount64 - lastVisit > 1000){_memoryCache.Set(cacheKey, Environment.TickCount64, TimeSpan.FromSeconds(10));await next();}else{context.Result = new ObjectResult("访问太频繁") { StatusCode=429};                    }}}}
    

示例2:

  1. RateLimitAttribute.cs
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.AspNetCore.Mvc.Filters;
    using Microsoft.Extensions.Caching.Memory;public class RateLimitAttribute : TypeFilterAttribute
    {public RateLimitAttribute(int maxRequests,int secondsWindow) : base(typeof(RateLimitFilter)){Arguments = new object[] { maxRequests,secondsWindow};}public class RateLimitFilter : IAsyncActionFilter{private readonly IMemoryCache _memoryCache;private readonly int _maxRequests;private readonly int _secondsWindow;public RateLimitFilter(IMemoryCache memoryCache, int maxRequests, int secondsWindow){_memoryCache = memoryCache;_maxRequests = maxRequests;_secondsWindow = secondsWindow;}public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next){var ip=context.HttpContext.Connection.RemoteIpAddress?.ToString();if (string.IsNullOrEmpty(ip)){context.Result = new BadRequestObjectResult("Invalid client IP");return;}var cacheKey = $"RateLimit_{ip}";var windowStart = DateTime.UtcNow.AddSeconds(-DateTime.UtcNow.Second % _secondsWindow);if (!_memoryCache.TryGetValue(cacheKey, out RateLimitCounter counter) ||windowStart > counter.WindowStart){counter = new RateLimitCounter{Count = 1,WindowStart = windowStart,};}else{counter.Count++;}if (counter.Count > _maxRequests){context.Result = new ObjectResult("Too many requests"){StatusCode = 429};return;}_memoryCache.Set(cacheKey, counter, counter.WindowStart.AddSeconds(_secondsWindow));await next();}private class RateLimitCounter{public int Count { get; set; }public DateTime WindowStart { get; set; }}}
    }
    

2)注册服务

  1. 内存缓存服务
    builder.Services.AddMemoryCache();
    

3)使用

  1. 示例:
    [HttpGet]
    //[RateLimit(maxRequests: 5, secondsWindow: 60)] // 每分钟最多5次请求
    [MyRateLimit]
    public async Task<ActionResult<Book>> GetAllBookAsync()
    {var res=await _bookRepository.GetAllAsync();return Ok(res);
    }
    

二、实现说明

  1. 使用IP地址识别客户端(需考虑代理场景)
  2. 基于固定时间窗口算法(每分钟/小时重置计数器)(示例2)
  3. 使用IMemoryCache存储计数器
  4. 返回429状态码(Too Many Requests)时阻止请求

总结

  1. 内存缓存方案仅适用于单实例部署
  2. 高并发场景建议使用Interlocked类处理计数器原子操作
  3. 生产环境推荐使用分布式缓存(如Redis
  4. 建议使用成熟的限流库(如AspNetCoreRateLimit

相关文章:

  • 在Window10 和 Ubuntu 24.04LTS 上 Ollama 在线或离线安装部署
  • 【ArUco boards】标定板检测
  • 详解RabbitMQ工作模式之路由模式
  • 适配器模式
  • 《 C++ 点滴漫谈: 三十六 》lambda表达式
  • Kotlin中 StateFlow 或 SharedFlow 或 LiveData的区别
  • 算力经济模型推演:从中心化到去中心化算力市场的转变(区块链+智能合约的算力交易原型设计)
  • Level DB --- MergingIterator
  • 数据结构之二叉树(4)
  • 【AI大模型】SpringBoot整合Spring AI 核心组件使用详解
  • PHP数组排序深度解析:sort()、rsort()、asort()、arsort()、ksort()、krsort() 的适用场景与性能对比
  • C++负载均衡远程调用学习之负载均衡算法与实现
  • 从零开始学习RAG
  • 《算法导论(第4版)》阅读笔记:p7-p8
  • FISCO BCOS【初体验笔记】
  • 嵌入式学习笔记 - STM32 SRAM控制器FSMC
  • RocketMQ与Kafka的区别
  • Nginx正反向代理与正则表达式
  • 从OpenMP中的不兼容,窥探AI应用开发中的并行编程
  • GStreamer开发笔记(三):测试gstreamer/v4l2+sdl2/v4l2+QtOpengl打摄像头延迟和内存
  • 公安部:“五一”假期全国社会大局稳定,治安秩序良好
  • 杨德龙:取得长期投资胜利法宝,是像巴菲特一样践行价值投资
  • 伊朗公布新型弹道导弹,“萨德”系统无法拦截
  • 局势紧张之际,伊朗外长下周访问巴基斯坦和印度
  • 中国企业转口贸易破局之道:出口国多元化,内外贸一体化
  • 竞彩湃|德甲保级白热化,都灵主帅直面旧主