并发请求太多,服务器崩溃了?试试使用 ASP.NET Core Web API 操作筛选器对请求进行限流

news/2024/10/19 11:46:41

Coding-7

前言

请求限流(Rate Limiting)主要是一种用于控制客户端对服务器的请求频率的机制。

其目的是限制客户端在一定时间内可以发送的请求数量,保护服务器免受过多请求的影响,确保系统的稳定性和可靠性。

请求限流通常会基于以下几个因素来进行限制:

  1. 时间窗口:规定了在多长时间内允许的请求次数
  2. 请求配额:在时间窗口内允许的最大请求数量
  3. 客户端标识:根据客户端的 IP 地址、用户标识或其他标识符来进行限流

请求限流技术可以应用在很多场景,本文主要讲述 ASP.NET Core Web API 如何使用操作筛选器对请求进行限流。

Step By Step 步骤

  1. 创建一个ASP.NET Core Web API 项目

  2. 编写自定义的操作筛选器 RateLimitFilter,实现 "1s内只允许最多有一个来自同一个IP地址的请求"(留意注释

    using Microsoft.AspNetCore.Mvc;
    using Microsoft.AspNetCore.Mvc.Filters;
    using Microsoft.Extensions.Caching.Memory;public class RateLimitFilter : IAsyncActionFilter
    {private readonly IMemoryCache memCache;// 注入的IMemoryCachepublic RateLimitFilter(IMemoryCache memCache){this.memCache = memCache;}public Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next){// 通过注入的 IMemoryCache 来记录用户上一次访问的时间戳// 在分布式系统下可以改用分布式缓存来代替内存缓存string removeIP = context.HttpContext.Connection.RemoteIpAddress!.ToString();string cacheKey = $"LastVisitTick_{removeIP}";// 从缓存中获取这个客户端IP地址上一次访问服务器的时间long? lastTick = memCache.Get<long?>(cacheKey);if (lastTick == null || Environment.TickCount64 - lastTick > 1000){// 如果缓存中不存在上一次访问时间或者上一次访问时间距离现在已经超过 1s,则通过 next 来执行后面的筛选器memCache.Set(cacheKey, Environment.TickCount64, TimeSpan.FromSeconds(10));return next();}else{// 否则说明 IP 频繁访问,不执行 next,相当于终止操作方法的执行context.Result = new ContentResult { StatusCode = 429 };return Task.CompletedTask;}}
    }
    

    代码中的内存缓存和分布式缓存可以参考本人之前文章《看看 Asp.net core Webapi 项目如何优雅地使用内存缓存》和《看看 Asp.net core Webapi 项目如何优雅地使用分布式缓存》

  3. 打开 Program.cs,注册这个操作筛选器

    using Microsoft.AspNetCore.Mvc;var builder = WebApplication.CreateBuilder(args);// Add services to the container.builder.Services.AddControllers();
    // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
    builder.Services.AddEndpointsApiExplorer();
    builder.Services.AddSwaggerGen();// 注册内存缓存服务
    builder.Services.AddMemoryCache();// 注册请求限流过滤器
    builder.Services.Configure<MvcOptions>(options => { options.Filters.Add<RateLimitFilter>();
    });var app = builder.Build();// Configure the HTTP request pipeline.
    if (app.Environment.IsDevelopment())
    {app.UseSwagger();app.UseSwaggerUI();
    }app.UseHttpsRedirection();app.UseAuthorization();app.MapControllers();app.Run();
    

测试

启动项目,并且访问接口,如果访问频率不高的话,接口能够正常工作。

如果访问频率很高的话,服务器就会提示 "Only once per second!"

总结

在操作筛选器中,通过 await next() 来执行下一个筛选器,

如果没有下一个筛选器,程序就会执行目标操作方法。

如果不调用 await next(),就可以终止操作方法的执行了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/73390.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

10.18 J 组模拟赛*2

上午 “J”组模拟赛 T1:一维围棋 题面 赛时:100 很简单的一道入门题,注意特判int n;char a[105];void init(){cin >> n;for (int i = 1; i <= n; i++)cin >> a[i];int mx = 0;for (int i = 1; i <= n; i++){if (a[i] == .){int lb = 0, rb = 0;for (int j …

AI人员打闹监测识别系统

AI人员打闹监测识别系统通过在校园、工厂和监狱场景部署高清摄像设备,AI人员打闹监测识别系统采集相关视频图像,并通过人工智能视觉算法对图像进行分析和识别。AI人员打闹监测识别系统能够准确判断出是否有人员进行打闹行为,包括学生打闹和工厂或监狱场景中的人员打架斗殴等…

强化学习的数学原理-01基本概念

state:\(The \quad status \quad of \quad agent \quad with \quad respect \quad to \quad the \quad environment\) (agent 相对于环境的状态) 对于下面的网格地图来说:\(state\)就相当于$ location $,用 \(s_1、s_2、...、s_9\)来表示state space:\(The \quad set…

煤矿监管电子封条

煤矿监管电子封条系统通过视频监控和图像分析技术,煤矿监管电子封条能够实时监测矿井各个关键位置的情况。当有人员进出或人数发生变化时,煤矿监管电子封条能够自动识别,并记录下相关信息。同时,煤矿监管电子封条还能够监测设备的开停情况,及时发现异常和故障,以便及时处…

keil 快捷键设置,开发加速的小技巧(个人设置)

点击扳手,选择shortcut key进入快捷键设置页面跳到上一个光标的位置跳到下一个光标的位置跳转到定义(没办法实现组合鼠标按键,F12又太远,不过和QQ的截图热键冲突,需要修改QQ的快捷键,各有取舍吧)跳转到声明

每隔一段时间后第一次请求耗时特别长

同一个接口连续请求耗时都是毫秒级别的,当一段时间不请求后会变成秒级别,通过日志跟踪发现业务出处理的时间是毫秒级别的,怀疑是过滤器或者是容器的问题,通过IDEA 远程debug 发现经过一段时间不使用再次请求接口,会寻找 com.mysql.jdbc.MySQLConnection类,猜测是tomcat 丢…

linux上编译运行c程序

创建test文件,进入该目录后创建hello.c文件使用vim hello.c命令编辑hello.c文件编写完成后保存该文件,使用gcc进行编译并生成可执行程序在终端中执行输入./hello执行相关代码

效率工具类软件分类解析 | To teacher

写给我的同仁的推荐信,万一你需要连你自己也说不清楚的功能软件,你不妨看看这个软件导图,说不定能节省你好多的时间 .前情概要 在编制博客过程中,自己也积累了一些常用的软件,由于主要工作内容集中在前端,所以办公软件使用的不是很多,零零散散,直到看到一位大牛分享在 …