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

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

时间:2024-10-19 11:32:03浏览次数:1  
标签:Core 缓存 请求 app 限流 筛选 builder

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;
    
    	// 注入的IMemoryCache
    	public 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(),就可以终止操作方法的执行了

标签:Core,缓存,请求,app,限流,筛选,builder
From: https://www.cnblogs.com/JackyGz/p/18475697

相关文章

  • 每隔一段时间后第一次请求耗时特别长
    同一个接口连续请求耗时都是毫秒级别的,当一段时间不请求后会变成秒级别,通过日志跟踪发现业务出处理的时间是毫秒级别的,怀疑是过滤器或者是容器的问题,通过IDEA远程debug发现经过一段时间不使用再次请求接口,会寻找 com.mysql.jdbc.MySQLConnection类,猜测是tomcat丢弃了已加......
  • WebView2 拦截查看所有的请求
    有两种方式:1.使用devtoolprotocol://启用网络监控awaitwebView.CoreWebView2.CallDevToolsProtocolMethodAsync("Network.enable","{}");//注册Network.requestWillBeSent事件varrequestWillBeSentReceiver=webView.CoreWebView2.GetDevToolsProtocolEv......
  • ASP.NET Core PDF viewers components Crack
    ASP.NETCorePDFviewerscomponentsCrackASP.NETCorePDFviewerscomponentswithformfillingsupportletusersdirectlycomplete,edit,andsubmitdatawithinPDFforms.TheabilitytoreadandwriteformfieldsinaPDFviewercomponenten......
  • Vue3 编写HTTP 请求工具并使用
    编写Http请求首先在vue项目中创建一个api工具包并新建http.js导入axiosimportaxiosfrom'axios';如果没有axios,那么要先下载一个下载axios配置axios默认设置设置了Axios的默认超时时间为5秒。允许跨域请求,通过设置 withCredentials 为 true。设置了POST请......
  • ArkWeb网络安全基础 - 跨域请求与解决方案
    本文旨在深入探讨华为鸿蒙HarmonyOSNext系统(截止目前API12)的技术细节,基于实际开发实践进行总结。主要作为技术分享与交流载体,难免错漏,欢迎各位同仁提出宝贵意见和问题,以便共同进步。本文为原创内容,任何形式的转载必须注明出处及原作者。简介华为鸿蒙HarmonyOSNext系统的Ar......
  • .netcore console 日志和配置
    前言做开发一般会写一些console程序进行调试或者小范围的处理,这里记录下console加日志和配置的过程日志日志这里选择serilog,serilog提供sink,控制台这里我们安装sink.Console和Sinke.File。一共三个nuget包SerilogSerilog.Sinks.ConsoleSerilog.Sinks.File然后代码中配......
  • MultipartEncoder处理request请求为表单数据时
    -----------------------------7e713d354f0fa6Content-Disposition:form-data;name="username"log_username-----------------------------7e713d354f0fa6Content-Disposition:form-data;name="password"log_pwd----------------------------......
  • ef core migrations 创建新的迁移程序
    EFCoreMigrations创建一个WebAPI.Migrationsdotnetnewwebapi-nWebAPI.MigrationsProgram.csusingSystem.Reflection;usingMicrosoft.Extensions.DependencyInjection;usingMicrosoft.EntityFrameworkCore;usingMicrosoft.Extensions.Configuration;usingDataA......
  • 【FastAPI】异步+网络请求
    前言:当我们碰到IO阻塞的时,使用fastapi异步框架,需要配合异步模块使用1.网络请求,httpximporthttpximportuvicornfromfastapiimportFastAPIfromfastapi.requestsimportRequestapp=FastAPI()@app.get("/api")asyncdefapi(request:Request):data_dict=......
  • CMSC Manual testing Completeness SNU Score
    Homework#3Due:Friday,October18that4:00pmCSTTableofContentsHomework#3GettingstartedManualtestingCompletenessSNUScoreCodeQualitySubmissionThepurposeofthisassignmentistogiveyouexperiencewithconditionals,lists,andloops.......