<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
在實際專案中,為了保障伺服器的穩定執行,需要對介面的可存取頻次進行限流控制,避免因使用者端頻繁請求導致伺服器壓力過大。
而AspNetCoreRateLimit
是目前ASP.NET Core
下最常用的限流解決方案。
檢視它的實現程式碼,我發現它使用的固定視窗演演算法。
var entry = await _counterStore.GetAsync(counterId, cancellationToken); if (entry.HasValue) { // entry has not expired if (entry.Value.Timestamp + rule.PeriodTimespan.Value >= DateTime.UtcNow) { // increment request count var totalCount = entry.Value.Count + _config.RateIncrementer?.Invoke() ?? 1; // deep copy counter = new RateLimitCounter { Timestamp = entry.Value.Timestamp, Count = totalCount }; } }
固定視窗演演算法是將時間線劃分為固定大小的視窗,併為每個視窗分配一個計數器。每個請求,根據其到達時間,被對映到一個視窗。如果視窗中的計數器已達到限制,則拒絕落在此視窗中的請求。
例如,如果我們將視窗大小設定為one分鐘,每分鐘允許ten個請求:
ASP.NET Core
基於滑動視窗演演算法實現限流控制 #yyds乾貨盤點#_滑動視窗
59秒的請求將被阻止,因為這時已經接受了10個請求。1分鐘時計數器歸零,所以1分01秒的請求可以接受。
固定視窗演演算法的問題主要在於,如果在視窗邊緣發生大量請求,會導致限流策略失效。
比如,在59秒接收了9個請求,在1分01秒又可以再接收10個請求,相當於每分鐘允許了20個請求。
滑動視窗類似於固定視窗演演算法,但它通過將前一個視窗中的加權計數新增到當前視窗中的計數來計算估計數,如果估計數超過計數限制,則請求將被阻止。
具體公式如下:
估計數 = 前一視窗計數 * (1 - 當前視窗經過時間 / 單位時間) + 當前視窗計數
例如,假設限制為每分鐘10個:
視窗[00:00, 00:01)中有9個請求,視窗[00:01, 00:02)中有5個請求。對於01:15到達的請求,即視窗[00:01, 00:02)的25%位置,通過公式計算請求計數:9 x (1 - 25%) + 5 = 11.75 > 10. 因此我們拒絕此請求。
即使兩個視窗都沒有超過限制,請求也會被拒絕,因為前一個和當前視窗的加權和確實超過了限制。
根據上面的公式,實現滑動視窗演演算法程式碼如下:
public class SlidingWindow { private readonly object _syncObject = new object(); private readonly int _requestIntervalSeconds; private readonly int _requestLimit; private DateTime _windowStartTime; private int _prevRequestCount; private int _requestCount; public SlidingWindow(int requestLimit, int requestIntervalSeconds) { _windowStartTime = DateTime.Now; _requestLimit = requestLimit; _requestIntervalSeconds = requestIntervalSeconds; } public bool PassRequest() { lock (_syncObject) { var currentTime = DateTime.Now; var elapsedSeconds = (currentTime - _windowStartTime).TotalSeconds; if (elapsedSeconds >= _requestIntervalSeconds * 2) { _windowStartTime = currentTime; _prevRequestCount = 0; _requestCount = 0; elapsedSeconds = 0; } else if (elapsedSeconds >= _requestIntervalSeconds) { _windowStartTime = _windowStartTime.AddSeconds(_requestIntervalSeconds); _prevRequestCount = _requestCount; _requestCount = 0; elapsedSeconds = (currentTime - _windowStartTime).TotalSeconds; } var requestCount = _prevRequestCount * (1 - elapsedSeconds / _requestIntervalSeconds) + _requestCount + 1; if (requestCount <= _requestLimit) { _requestCount++; return true; } } return false; } }
如果最近的2次請求相距2個視窗時間,則可以認為前一視窗計數為0,重新開始計數。
新建Middleware,使用滑動視窗演演算法進行限流:
public class RateLimitMiddleware : IMiddleware { private readonly SlidingWindow _window; public RateLimitMiddleware() { _window = new SlidingWindow(10, 60); } public async Task InvokeAsync(HttpContext context, RequestDelegate next) { if (!_window.PassRequest()) { context.SetEndpoint(new Endpoint((context) => { context.Response.StatusCode = StatusCodes.Status403Forbidden; return Task.CompletedTask; }, EndpointMetadataCollection.Empty, "限流")); } await next(context); } }
需要注意的是,我們註冊Middleware
時,必須使用單例模式,保證所有請求通過同一SlidingWindow計數:
services.AddSingleton<RateLimitMiddleware>();
使用滑動視窗演演算法,可以有效避免固定視窗演演算法存在的視窗邊緣大量請求無法限制的問題。
到此這篇關於ASP.NET Core基於滑動視窗實現限流控制的文章就介紹到這了,更多相關ASP.NET Core基於滑動視窗實現限流控制內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45