前言
Microsoft.AspNetCore.ConcurrencyLimiter AspNetCore3.0后增加的,用于傳入的請求進行排隊處理,避免線程池的不足.
我們日常開發中可能常做的給某web服務器配置連接數以及,請求隊列大小,那么今天我們看看如何在通過中間件形式實現一個并發量以及隊列長度限制.
Queue策略
添加Nuget
Install-Package Microsoft.AspNetCore.ConcurrencyLimiter
public void ConfigureServices(IServiceCollection services) { services.AddQueuePolicy(options => { //最大并發請求數 options.MaxConcurrentRequests = 2; //請求隊列長度限制 options.RequestQueueLimit = 1; }); services.AddControllers(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { //添加并發限制中間件 app.UseConcurrencyLimiter(); app.Run(async context => { Task.Delay(100).Wait(); // 100ms sync-over-async await context.Response.WriteAsync("Hello World!"); }); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } 通過上面簡單的配置,我們就可以將他引入到我們的代碼中,從而做并發量限制,以及隊列的長度;那么問題來了,他是怎么實現的呢?
public static IServiceCollection AddQueuePolicy(this IServiceCollection services, Action<QueuePolicyOptions> configure){ services.Configure(configure); services.AddSingleton<IQueuePolicy, QueuePolicy>(); return services;}QueuePolicy采用的是SemaphoreSlim信號量設計,SemaphoreSlim、Semaphore(信號量)支持并發多線程進入被保護代碼,對象在初始化時會指定 最大任務數量,當線程請求訪問資源,信號量遞減,而當他們釋放時,信號量計數又遞增。
/// <summary> /// 構造方法(初始化Queue策略) /// </summary> /// <param name="options"></param> public QueuePolicy(IOptions<QueuePolicyOptions> options) { _maxConcurrentRequests = options.Value.MaxConcurrentRequests; if (_maxConcurrentRequests <= 0) { throw new ArgumentException(nameof(_maxConcurrentRequests), "MaxConcurrentRequests must be a positive integer."); } _requestQueueLimit = options.Value.RequestQueueLimit; if (_requestQueueLimit < 0) { throw new ArgumentException(nameof(_requestQueueLimit), "The RequestQueueLimit cannot be a negative number."); } //使用SemaphoreSlim來限制任務最大個數 _serverSemaphore = new SemaphoreSlim(_maxConcurrentRequests); }ConcurrencyLimiterMiddleware中間件
新聞熱點
疑難解答
圖片精選