淺析如何在?ASP.NET?Core中實(shí)現(xiàn)速率限制
在 ASP.NET Core 中實(shí)現(xiàn)速率限制(Rate Limiting)中間件可以幫助你控制客戶端對(duì) API 的請(qǐng)求頻率,防止濫用和過(guò)載。速率限制通常用于保護(hù)服務(wù)器資源,確保服務(wù)的穩(wěn)定性和可用性。
ASP.NET Core 本身并沒(méi)有內(nèi)置的速率限制中間件,但你可以通過(guò)自定義中間件或使用第三方庫(kù)來(lái)實(shí)現(xiàn)速率限制。以下是實(shí)現(xiàn)速率限制的幾種常見(jiàn)方法:
1. 使用自定義中間件實(shí)現(xiàn)速率限制
你可以通過(guò)自定義中間件來(lái)實(shí)現(xiàn)速率限制。以下是一個(gè)簡(jiǎn)單的實(shí)現(xiàn)示例:
1.1 實(shí)現(xiàn)速率限制中間件
using Microsoft.AspNetCore.Http; using System.Collections.Concurrent; using System.Threading.Tasks; public class RateLimitingMiddleware { private readonly RequestDelegate _next; private readonly int _maxRequests; // 每分鐘允許的最大請(qǐng)求數(shù) private readonly ConcurrentDictionary<string, RateLimiter> _rateLimiters; public RateLimitingMiddleware(RequestDelegate next, int maxRequests) { _next = next; _maxRequests = maxRequests; _rateLimiters = new ConcurrentDictionary<string, RateLimiter>(); } public async Task InvokeAsync(HttpContext context) { // 獲取客戶端的唯一標(biāo)識(shí)(例如 IP 地址) var clientId = context.Connection.RemoteIpAddress.ToString(); // 獲取或創(chuàng)建速率限制器 var rateLimiter = _rateLimiters.GetOrAdd(clientId, _ => new RateLimiter(_maxRequests)); if (rateLimiter.AllowRequest()) { await _next(context); } else { context.Response.StatusCode = StatusCodes.Status429TooManyRequests; await context.Response.WriteAsync("請(qǐng)求太多。請(qǐng)稍后再試."); } } } public class RateLimiter { private readonly int _maxRequests; private int _requestCount; private DateTime _windowStart; public RateLimiter(int maxRequests) { _maxRequests = maxRequests; _requestCount = 0; _windowStart = DateTime.UtcNow; } public bool AllowRequest() { var now = DateTime.UtcNow; // 如果當(dāng)前時(shí)間窗口已過(guò)期,重置計(jì)數(shù)器 if ((now - _windowStart).TotalSeconds > 60) { _requestCount = 0; _windowStart = now; } // 檢查請(qǐng)求是否超出限制 if (_requestCount < _maxRequests) { _requestCount++; return true; } return false; } }
1.2 注冊(cè)中間件
在 Startup.cs
中注冊(cè)中間件:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseMiddleware<RateLimitingMiddleware>(10); // 每分鐘最多 10個(gè)請(qǐng)求 app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
2. 使用第三方庫(kù)實(shí)現(xiàn)速率限制
如果你不想自己實(shí)現(xiàn)速率限制邏輯,可以使用一些現(xiàn)成的第三方庫(kù),例如:
AspNetCoreRateLimit
AspNetCoreRateLimit 是一個(gè)流行的 ASP.NET Core 速率限制庫(kù),支持 IP 地址、客戶端 ID 和端點(diǎn)級(jí)別的速率限制。
安裝
通過(guò) NuGet 安裝:
dotnet add package AspNetCoreRateLimit
配置
在 Startup.cs
中配置速率限制:
public void ConfigureServices(IServiceCollection services) { // 添加內(nèi)存緩存 services.AddMemoryCache(); // 配置速率限制 services.Configure<IpRateLimitOptions>(Configuration.GetSection("IpRateLimiting")); services.AddSingleton<IIpPolicyStore, MemoryCacheIpPolicyStore>(); services.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>(); services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>(); services.AddSingleton<IProcessingStrategy, AsyncKeyLockProcessingStrategy>(); services.AddInMemoryRateLimiting(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseIpRateLimiting(); app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
配置文件
在 appsettings.json
中添加速率限制配置:
{ "IpRateLimiting": { "EnableEndpointRateLimiting": true, "StackBlockedRequests": false, "RealIpHeader": "X-Real-IP", "ClientIdHeader": "X-ClientId", "GeneralRules": [ { "Endpoint": "*", "Period": "1m", "Limit": 10 } ] } }
3. 使用分布式緩存實(shí)現(xiàn)速率限制
如果你的應(yīng)用是分布式的(例如部署在 Kubernetes 或多個(gè)服務(wù)器上),可以使用分布式緩存(如 Redis)來(lái)實(shí)現(xiàn)速率限制。
3.1 使用 Redis 實(shí)現(xiàn)速率限制
你可以使用 Redis 來(lái)存儲(chǔ)每個(gè)客戶端的請(qǐng)求計(jì)數(shù)。以下是一個(gè)簡(jiǎn)單的示例:
using Microsoft.AspNetCore.Http; using StackExchange.Redis; using System.Threading.Tasks; public class RedisRateLimitingMiddleware { private readonly RequestDelegate _next; private readonly int _maxRequests; private readonly ConnectionMultiplexer _redis; public RedisRateLimitingMiddleware(RequestDelegate next, int maxRequests, ConnectionMultiplexer redis) { _next = next; _maxRequests = maxRequests; _redis = redis; } public async Task InvokeAsync(HttpContext context) { var clientId = context.Connection.RemoteIpAddress.ToString(); var db = _redis.GetDatabase(); var key = $"rate_limit:{clientId}"; var requestCount = await db.StringIncrementAsync(key); if (requestCount == 1) { await db.KeyExpireAsync(key, TimeSpan.FromMinutes(1)); } if (requestCount > _maxRequests) { context.Response.StatusCode = StatusCodes.Status429TooManyRequests; await context.Response.WriteAsync("請(qǐng)求太多。請(qǐng)稍后再試."); } else { await _next(context); } } }
3.2 注冊(cè)中間件
在 Startup.cs
中注冊(cè)中間件:
public void ConfigureServices(IServiceCollection services) { services.AddSingleton<ConnectionMultiplexer>(ConnectionMultiplexer.Connect("localhost:6379")); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseMiddleware<RedisRateLimitingMiddleware>(10); // 每分鐘最多 10個(gè)請(qǐng)求 app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
4. 總結(jié)
在 ASP.NET Core 中實(shí)現(xiàn)速率限制有多種方式:
- 自定義中間件:適合簡(jiǎn)單的場(chǎng)景,但需要自己實(shí)現(xiàn)邏輯。
- 第三方庫(kù):如 AspNetCoreRateLimit,提供了更強(qiáng)大的功能和靈活性。
- 分布式緩存:如 Redis,適合分布式環(huán)境。
根據(jù)你的需求選擇合適的方式,確保你的 API 能夠有效防止濫用和過(guò)載。
到此這篇關(guān)于淺析如何在 ASP.NET Core中實(shí)現(xiàn)速率限制的文章就介紹到這了,更多相關(guān)ASP.NET Core速率限制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Asp.net ajax實(shí)現(xiàn)任務(wù)提示頁(yè)面的簡(jiǎn)單代碼
這篇文章介紹了Asp.net ajax實(shí)現(xiàn)任務(wù)提示頁(yè)面的簡(jiǎn)單代碼,有需要的朋友可以參考一下2013-11-11ASP.NET?Core使用EF?SQLite對(duì)數(shù)據(jù)庫(kù)增刪改查
這篇文章介紹了ASP.NET?Core使用EF?SQLite對(duì)數(shù)據(jù)庫(kù)增刪改查的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-01-01ASP.NET 2.0下隨機(jī)讀取Access記錄的實(shí)現(xiàn)方法
ASP.NET 2.0下隨機(jī)讀取Access記錄的實(shí)現(xiàn)方法...2007-03-03asp.net畫(huà)曲線圖(折線圖)代碼 詳細(xì)注釋
asp.net畫(huà)曲線圖(折線圖), 需要的朋友可以參考下。2010-03-03利用.net控件實(shí)現(xiàn)下拉導(dǎo)航菜單制作的具體方法
這篇文章介紹了利用.net控件實(shí)現(xiàn)下拉導(dǎo)航菜單制作的具體方法,有需要的朋友可以參考一下,希望對(duì)你有所幫助2013-07-07如何判斷?.NET?Core?應(yīng)用程序以管理員身份運(yùn)行的
這篇文章主要介紹了如何判斷?.NET?Core?應(yīng)用程序是以管理員身份運(yùn)行的,我們需要知道當(dāng)前程序是否以管理員身份運(yùn)行,以便執(zhí)行一些需要特殊權(quán)限的操作,下面為我們就來(lái)學(xué)習(xí)具體的方法吧,需要的朋友可以參考一下2022-03-03net core webapi多版本控制與swagger(nswag)配置教程
這篇文章主要介紹了net core webapi多版本控制與swagger(nswag)配置,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11ASP.NET Core實(shí)現(xiàn)多文件上傳
這篇文章介紹了ASP.NET Core實(shí)現(xiàn)多文件上傳的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-01-01asp.net 簡(jiǎn)單實(shí)現(xiàn)禁用或啟用頁(yè)面中的某一類型的控件
最近在一個(gè)winform項(xiàng)目中碰到的一個(gè)功能,勾選一個(gè)checkbox后窗體中的其他控件不可用。由此想到asp.net項(xiàng)目中有時(shí)候也要用到這種功能。2009-11-11