国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

ASP.NET Core 6框架揭秘實例演示[38]:兩種不同的限流策略

這篇具有很好參考價值的文章主要介紹了ASP.NET Core 6框架揭秘實例演示[38]:兩種不同的限流策略。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

承載ASP.NET應(yīng)用的服務(wù)器資源總是有限的,短時間內(nèi)涌入過多的請求可能會瞬間耗盡可用資源并導(dǎo)致宕機。為了解決這個問題,我們需要在服務(wù)端設(shè)置一個閥門將并發(fā)處理的請求數(shù)量限制在一個可控的范圍,即使會導(dǎo)致請求的延遲響應(yīng),在極端的情況會還不得不放棄一些請求。ASP.NET應(yīng)用的流量限制是通過ConcurrencyLimiterMiddleware中間件實現(xiàn)的。(本文提供的示例演示已經(jīng)同步到《ASP.NET Core 6框架揭秘-實例演示版》)

[S2601]設(shè)置并發(fā)和等待請求閾值 (源代碼)
[S2602]基于隊列的限流策略(源代碼)
[S2603]基于棧的限流策略(源代碼)
[S2604]處理被拒絕的請求(源代碼)

[S2601]設(shè)置并發(fā)和等待請求閾值

由于各種Web服務(wù)器、反向代理和負載均衡器都提供了限流的能力,我們很少會在應(yīng)用層面進行流量控制。ConcurrencyLimiterMiddleware中間件由“Microsoft.AspNetCore.ConcurrencyLimiter”這個NuGet包提供,ASP.NET應(yīng)用采用的SDK(“Microsoft.NET.Sdk.Web”)并沒有將該包作為默認的引用,所以我們需要手工添加該NuGet包的引用。

當請求并發(fā)量超過設(shè)定的閾值,ConcurrencyLimiterMiddleware中間件會將請求放到等待隊列中,整個限流工作都是圍繞這個這個隊列進行的,采用怎樣的策略管理這個等待隊列是整個限流模型的核心。不論采用何種策略,我們都需要設(shè)置兩個閾值,一個是當前允許的最大并發(fā)請求量,另一個是等待隊列的最大容量。如代碼片段所示,我們通過調(diào)用IServiceCollection接口的AddQueuePolicy擴展方法注冊了一個基于隊列(“Queue”)的策略,并將上述的兩個閾值設(shè)置為2。

using App;

var builder = WebApplication.CreateBuilder(args);
builder.Logging.ClearProviders();
builder.Services
    .AddHostedService<ConsumerHostedService>()
    .AddQueuePolicy(options =>
    {
        options.MaxConcurrentRequests = 2;
        options.RequestQueueLimit = 2;
    });
var app = builder.Build();
app
    .UseConcurrencyLimiter()
    .Run(httpContext => Task.Delay(1000).ContinueWith(_ => httpContext.Response.StatusCode = 200));
app.Run();
ConcurrencyLimiterMiddleware中間件是通過調(diào)用IApplicationBuilder的UseConcurrencyLimiter擴展方法進行注冊的。后續(xù)通過調(diào)用Run擴展方法提供的RequestDelegate委托模擬了一秒鐘的處理耗時。我們演示的程序還注冊了一個ConsumerHostedService類型的承載服務(wù)來模擬消費API的客戶端。如下面的代碼片段所示,ConsumerHostedService利用注入的IConfiguration對象來提供并發(fā)量配置。當此承載服務(wù)啟動之后,它會根據(jù)配置創(chuàng)建相應(yīng)數(shù)量的并發(fā)任務(wù)持續(xù)地對我們的應(yīng)用發(fā)起請求。
public class ConsumerHostedService : BackgroundService
{
    private readonly HttpClient[] _httpClients;
    public ConsumerHostedService(IConfiguration configuration)
    {
        var concurrency = configuration.GetValue<int>("Concurrency");
        _httpClients = Enumerable
            .Range(1, concurrency)
            .Select(_ => new HttpClient())
            .ToArray();
    }

    protected override Task ExecuteAsync(CancellationToken stoppingToken)
    {
        var tasks = _httpClients.Select(async client =>
        {
            while (true)
            {
                var start = DateTimeOffset.UtcNow;
                var response = await client.GetAsync("http://localhost:5000");
                var duration = DateTimeOffset.UtcNow - start;
                var status = $"{(int)response.StatusCode},{response.StatusCode}";
                Console.WriteLine($"{status} [{(int)duration.TotalSeconds}s]");
                if (!response.IsSuccessStatusCode)
                {
                    await Task.Delay(1000);
                }
            }
        });
        return Task.WhenAll(tasks);
    }

    public override Task StopAsync(CancellationToken cancellationToken)
    {
        Array.ForEach(_httpClients, it => it.Dispose());
        return Task.CompletedTask;
    }
}

對于發(fā)送的每個請求,ConsumerHostedService都會在控制臺上記錄下響應(yīng)的狀態(tài)和耗時。為了避免控制臺“刷屏”,我們在接收到錯誤響應(yīng)后模擬一秒鐘的等待。由于并發(fā)量是由配置系統(tǒng)提供的,所以我們可以利用命令行參數(shù)(“Concurrency”)的方式來對并發(fā)量進行設(shè)置。如圖1所示,我們以命令行的方式啟動了程序,并通過命令行參數(shù)將并發(fā)量設(shè)置為2。由于并發(fā)量并沒有超出閾值,所以每個請求均得到正常的響應(yīng)。

ASP.NET Core 6框架揭秘實例演示[38]:兩種不同的限流策略

圖1 并發(fā)量未超出閾值

由于并發(fā)量的閾值和等待隊列的容量均設(shè)置為2,從外部來看,我們的演示程序所能承受的最大并發(fā)量為4。所以當我們以此并發(fā)量啟動程序之后,并發(fā)的請求能夠接收到成功的響應(yīng),但是除了前兩個請求能夠得到及時處理之外,后續(xù)請求都會在等待隊列中呆上一段時間,所以整個耗時會延長。如果將并發(fā)量提升到5,這顯然超出了服務(wù)端的極限,所以部分請求會得到狀態(tài)碼為“503, Service Unavailable”的響應(yīng)。

ASP.NET Core 6框架揭秘實例演示[38]:兩種不同的限流策略

圖2 并發(fā)量超出閾值

ASP.NET應(yīng)用的并發(fā)處理的請求量可以通過dotnet-counters工具提供的性能計數(shù)器進行查看。具體的性能計數(shù)器名稱為“Microsoft.AspNetCore.Hosting”,我們現(xiàn)在通過這種方式來看看應(yīng)用程序真正的并發(fā)處理指標是否和我們的預(yù)期一致。我們還是以并發(fā)量為5啟動演示程序,然后以圖26-3所示的方式執(zhí)行“dotnet-coutners ps”命令查看演示程序的進程,并針對進程ID執(zhí)行“dotnet-counters monitor”命令查看名為“Microsoft.AspNetCore.Hosting”的性能指標。

ASP.NET Core 6框架揭秘實例演示[38]:兩種不同的限流策略

圖3 使用dotnet-counters monitor查看并發(fā)量

如圖3所示,dotnet-counters顯示的并發(fā)請求為4,這和我們的設(shè)置是吻合的,因為對于應(yīng)用的中間件管道來說,并發(fā)處理的請求包含ConcurrencyLimiterMiddleware中間件的等待隊列的兩個和后續(xù)中間件真正處理的兩個。我們還看到了每秒處理的請求數(shù)量為3,并有約1/3的請求失敗率,這些指標和我們的設(shè)置都是吻合的。

[S2602]基于隊列的限流策略

通過前面的示例演示我們知道,當ConcurrencyLimiterMiddleware中間件維護的等待隊列被填滿并且后續(xù)中間件管道正在“滿負荷運行(并發(fā)處理的請求達到設(shè)定的閾值)”的情況下,如果此時接收到一個新的請求,它只能放棄某個待處理的請求。具體來說,它具有兩種選擇,一種是放棄剛剛接收的請求,另一種就是將等待隊列中的某個請求扔掉,其位置由新接收的請求占據(jù)。

前面演示實例采用的等待隊列處理策略是通過調(diào)用IServiceCollection接口的AddQueuePolicy擴展方法注冊的,這樣一種基于“隊列”的策略。我們知道隊列的特點就是先進先出(FIFO),講究“先來后到”,如果采用這種策略就會放棄剛剛接收到的請求。我們可以通過簡單的實例證實這一點。如下面的演示程序所示,我們在ConcurrencyLimiterMiddleware中間件之前注冊了一個通過DiagnosticMiddleware方法表示的中間件,它會對每個請求按照它接收到的時間順序進行編號,我們利用它打印出每個請求對應(yīng)的響應(yīng)狀態(tài)就知道ConcurrencyLimiterMiddleware中間件最終放棄的是那個請求了。

using App;

var requestId = 1;
var @lock = new object();

var builder = WebApplication.CreateBuilder();
builder.Logging.ClearProviders();
builder.Services
    .AddHostedService<ConsumerHostedService>()
    .AddQueuePolicy(options =>
    {
        options.MaxConcurrentRequests 	= 2;
        options.RequestQueueLimit 	= 2;
    });
var app = builder.Build();
app
    .Use(InstrumentAsync)
    .UseConcurrencyLimiter()
    .Run(httpContext => Task.Delay(1000).ContinueWith(_ => httpContext.Response.StatusCode = 200));
await app.StartAsync();

var tasks = Enumerable.Range(1, 5)
    .Select(_ => new HttpClient().GetAsync("http://localhost:5000"));
await Task.WhenAll(tasks);
Console.Read();

async Task InstrumentAsync(HttpContext httpContext, RequestDelegate next)
{
    Task task;
    int id;
    lock (@lock!)
    {
        id = requestId++;
        task = next(httpContext);
    }
    await task;
    Console.WriteLine($"Request {id}: {httpContext.Response.StatusCode}");
}

我們在 IServiceCollection接口的AddQueuePolicy擴展方法中提供的設(shè)置不變(最大并發(fā)量和等待隊列大小都是2)。在應(yīng)用啟動之后,我們同時發(fā)送了5個請求,此時控制臺上會呈現(xiàn)出如圖4所示的輸出結(jié)果,可以看出ConcurrencyLimiterMiddleware中間件在接收到第5個請求并不得不作出取舍的時候,它放棄的就是當前接收到的請求。

ASP.NET Core 6框架揭秘實例演示[38]:兩種不同的限流策略

圖4 基于隊列的處理策略

[S2603]基于棧的限流策略

當ConcurrencyLimiterMiddleware中間件在接收到某個請求并需要決定放棄某個待處理請求時,它還可以采用另一種基于“棧”的策略。如果采用這種策略,它會先保全當前接收到的請求,并用它替換掉存儲在等待隊列時間最長的那個。也就是說它不再講究先來后到,而主張后來居上。對于前面演示的程序來說,我們只需要按照如下的方式將針對AddQueuePolicy擴展方法的調(diào)用替換成AddStackPolicy方法就可以切換到這種策略。

...
var builder = WebApplication.CreateBuilder();
builder.Logging.ClearProviders();
builder.Services
    .AddHostedService<ConsumerHostedService>()
    .AddStackPolicy(options =>
    {
        options.MaxConcurrentRequests 	= 2;
        options.RequestQueueLimit 	= 2;
    });
var app = builder.Build();
...

重新啟動改動后的演示程序,我們將在控制臺上得到如圖5所示的輸出結(jié)果??梢钥闯鲞@次ConcurrencyLimiterMiddleware中間件在接收到第5個請求并不得不做出取舍的時候,它放棄的就是最先存儲到等待隊列的第3個請求。

ASP.NET Core 6框架揭秘實例演示[38]:兩種不同的限流策略

圖5 基于棧處理策略

[S2604]處理被拒絕的請求

從ConcurrencyLimiterMiddleware中間件的實現(xiàn)可以看出,在默認情況下因超出限流閾值而被拒絕處理的請求來說,應(yīng)用最終會給與一個狀態(tài)碼為“503 Service Available”的響應(yīng)。如果我們對這個默認的處理方式不滿意,可以通過對配置選項ConcurrencyLimiterOptions的設(shè)置來提供一個自定義的處理器。舉個典型的場景,集群部署的多臺機器可能負載不均,所以如果將被某臺機器拒絕的請求分發(fā)給另一臺機器是可能被正常處理的。為了確保請求能夠盡可能地被處理,我們可以針對相同的URL發(fā)起一個客戶端重定向,具體的實現(xiàn)體現(xiàn)在如下所示的演示程序中。

using Microsoft.AspNetCore.ConcurrencyLimiter;
using Microsoft.AspNetCore.Http.Extensions;

var builder = WebApplication.CreateBuilder(args);
builder.Logging.ClearProviders();
builder.Services
   .Configure<ConcurrencyLimiterOptions>(options => options.OnRejected = RejectAsync)
   .AddStackPolicy(options =>
    {
        options.MaxConcurrentRequests 	= 2;
        options.RequestQueueLimit 	= 2;
    });
var app = builder.Build();
app
    .UseConcurrencyLimiter()
    .Run(httpContext => Task.Delay(1000).ContinueWith(_ => httpContext.Response.StatusCode = 200));
app.Run();

static Task RejectAsync(HttpContext httpContext)
{
    var request = httpContext.Request;
    if (!request.Query.ContainsKey("reject"))
    {
        var response = httpContext.Response;
        response.StatusCode = 307;
        var queryString = request.QueryString.Add("reject", "true");
        var newUrl = UriHelper.BuildAbsolute(request.Scheme, request.Host, request.PathBase, request.Path, queryString);
        response.Headers.Location = newUrl;
    }
    return Task.CompletedTask;
}

如上面的代碼片段所示,我們調(diào)用IServiceCollection接口的Configure<TOptions>擴展方法對ConcurrencyLimiterOptions進行了配置。具體來說,我們將RejectAsync方法表示的RequestDelegate委托作為拒絕請求處理器賦值給了ConcurrencyLimiterOptions配置選項的OnRejected屬性。在RejectAsync方法中,我們針對當前請求的URL返回了一個狀態(tài)碼為307的臨時重定向響應(yīng)。為了避免重復(fù)的重定向操作,我們?yōu)橹囟ㄏ虻刂诽砑恿艘粋€名為“reject”的查詢字符串來識別重定向請求。文章來源地址http://www.zghlxwxcb.cn/news/detail-481842.html

到了這里,關(guān)于ASP.NET Core 6框架揭秘實例演示[38]:兩種不同的限流策略的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 詳解ASP.NET Core 在 IIS 下的兩種部署模式

    詳解ASP.NET Core 在 IIS 下的兩種部署模式

    KestrelServer最大的優(yōu)勢體現(xiàn)在它的跨平臺的能力,如果ASP.NET CORE應(yīng)用只需要部署在Windows環(huán)境下,IIS也是不錯的選擇。ASP.NET CORE應(yīng)用針對IIS具有兩種部署模式,它們都依賴于一個IIS針對ASP.NET CORE Core的擴展模塊。 IIS其實也是按照管道的方式來處理請求的,但是IIS管道和ASP.NET CO

    2024年02月10日
    瀏覽(23)
  • asp.net core 框架搭建2-搭建MVC后臺管理系統(tǒng)

    asp.net core 框架搭建2-搭建MVC后臺管理系統(tǒng)

    作者:xcLeigh 文章地址:https://blog.csdn.net/weixin_43151418/article/details/131458964 asp.net core 框架搭建2-搭建MVC后臺管理系統(tǒng) ,本文章介紹asp.net core框架搭建,然后開發(fā)一個后臺管理系統(tǒng),將一步步帶著大家,實現(xiàn)目標。所有操作過程將展現(xiàn)在本篇文章,下面咋們一起來實現(xiàn)它吧。 使

    2024年02月12日
    瀏覽(20)
  • ASP.NET Core使用JWT+標識框架(identity)實現(xiàn)登錄驗證

    ASP.NET Core使用JWT+標識框架(identity)實現(xiàn)登錄驗證

    最近閱讀了《ASP.NET Core 技術(shù)內(nèi)幕與項目實戰(zhàn)——基于DDD與前后端分離》(作者楊中科)的第八章,對于Core入門的我來說體會頗深,整理相關(guān)筆記。 JWT:全稱“JSON web toke”,目前流行的跨域身份驗證解決方案; 標識框架(identity):由ASP.NET Core提供的框架,它采用RBAC(role

    2024年02月11日
    瀏覽(25)
  • 【ASP.NET Core 基礎(chǔ)知識】--MVC框架--Models和數(shù)據(jù)綁定

    Models和數(shù)據(jù)綁定在ASP.NET Core MVC中扮演著關(guān)鍵的角色,對于構(gòu)建強大、靈活和可維護的Web應(yīng)用程序至關(guān)重要。這一節(jié)我們就來講一下。 一、Models 1.1 Models的定義和作用 在ASP.NET Core MVC中,Model是應(yīng)用程序中用于表示數(shù)據(jù)結(jié)構(gòu)和業(yè)務(wù)邏輯的一種抽象。Models充當了MVC(Model-View-Contr

    2024年01月23日
    瀏覽(93)
  • asp.net core框架搭建1-搭建webapi,對數(shù)據(jù)增刪改查接口模板(附源碼)

    asp.net core框架搭建1-搭建webapi,對數(shù)據(jù)增刪改查接口模板(附源碼)

    作者:xcLeigh 文章地址:https://blog.csdn.net/weixin_43151418/article/details/131458922 asp.net core 框架搭建2-搭建webapi ,本文章介紹asp.net core webapi框架搭建,然后開發(fā)增刪改查和工具接口,將一步步帶著大家,實現(xiàn)目標。所有操作過程將展現(xiàn)在本篇文章,下面咋們一起來實現(xiàn)它吧。 asp.ne

    2024年02月13日
    瀏覽(21)
  • dotnet 簡單方法在一個進程內(nèi)同時跑起 WPF 和 ASP.NET Core 框架

    dotnet 簡單方法在一個進程內(nèi)同時跑起 WPF 和 ASP.NET Core 框架

    從設(shè)計架構(gòu)上,無論是 WPF 還是 ASP.NET Core 框架,都是在 dotnet 運行時上層的應(yīng)用,兩個框架處于平級的結(jié)構(gòu)。理論上講,兩個平級的框架只要不存在特殊的情況,都是能夠相容存在的。本文將和大家介紹一個非常簡單的方法,在一個進程內(nèi)同時跑起 WPF 和 ASP.NET Core 框架 在一

    2024年04月26日
    瀏覽(29)
  • 如何在ASP.NET Core應(yīng)用中實現(xiàn)與第三方IoC/DI框架的整合?

    如何在ASP.NET Core應(yīng)用中實現(xiàn)與第三方IoC/DI框架的整合?

    我們知道整個ASP.NET Core建立在以ServiceCollection/ServiceProvider為核心的DI框架上,它甚至提供了擴展點使我們可以與第三方DI框架進行整合。對此比較了解的讀者朋友應(yīng)該很清楚,針對第三方DI框架的整合可以通過在定義Startup類型的ConfigureServices方法返回一個ServiceProvider來實現(xiàn)。但

    2024年02月09日
    瀏覽(32)
  • 《深入淺出.NET框架設(shè)計與實現(xiàn)》筆記6.2——ASP.NET Core應(yīng)用程序多種運行模式之二——IIS 服務(wù)承載

    ?ASP.NET Core應(yīng)用程序可以在多種運行模式下運行,包括自宿主(Self-Hosting)、IIS服務(wù)承載、桌面應(yīng)用程序、服務(wù)承載。 因此選擇和時的模式很重要。 IIS 服務(wù)承載 將 ASP.NET Core 應(yīng)用程序托管在 Internet Information Services (IIS) 中。 利用 IIS 提供的高級功能,如負載均衡、HTTPS 支持和

    2024年04月26日
    瀏覽(20)
  • ASP.Net Core Web API結(jié)合Entity Framework Core框架(API的創(chuàng)建使用,接口前端權(quán)限設(shè)置,前端獲取API的Get,post方法)(程序包引用以及導(dǎo)入數(shù)據(jù)庫)

    ASP.Net Core Web API結(jié)合Entity Framework Core框架(API的創(chuàng)建使用,接口前端權(quán)限設(shè)置,前端獲取API的Get,post方法)(程序包引用以及導(dǎo)入數(shù)據(jù)庫)

    目錄 1. Web Api 程序包引用 2. Web Api 的創(chuàng)建與Http類型的介紹 2.1?ASP.Net Core Web API項目的創(chuàng)建 2?.2? API接口的創(chuàng)建 2.3?HttpGet和HttpPost類型的區(qū)別 3.接口權(quán)限設(shè)置 4.HttpGet方法和HttpPOst方法 5.前端中用HttpGet/Poset獲取接口數(shù)據(jù) 6.EF框架——配置數(shù)據(jù)庫鏈接字符串(即將數(shù)據(jù)庫中的表導(dǎo)入項

    2024年02月08日
    瀏覽(31)
  • ASP.NET Core教程:ASP.NET Core 程序部署到Windows系統(tǒng)

    ASP.NET Core教程:ASP.NET Core 程序部署到Windows系統(tǒng)

    本篇文章介紹如何將一個ASP.NET Core Web程序部署到Windows系統(tǒng)上。這里以ASP.NET Core WebApi為例進行講解。首先創(chuàng)建一個ASP.NET Core WebApi項目,使用默認的Values控制器,這里使用Visual Studio 2019創(chuàng)建一個ASP.NET Core 3.1d的WebApi項目。 創(chuàng)建新項目的時候選項ASP.NET Core Web應(yīng)用程序,如下圖所

    2023年04月08日
    瀏覽(103)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包