dimmits
dimmits

Reputation: 2339

Limit concurrent requests in .net core

I am trying to configure my .net core API in order to limit the requests.

To achieve this i modify the program.cs class like

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();            
    }


    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.ConfigureKestrel(serverOptions =>
                {
                    serverOptions.Limits.MaxConcurrentConnections = 2;
                })
                //.UseContentRoot(Directory.GetCurrentDirectory())
                //.UseIISIntegration()
                .UseStartup<Startup>();
            });
}

but the problem is when I call my API with a console app using more threads than 2 I get the responses from all threads-calls. The API I have deployed-published it in my local IIS pc.

I consider that I must get only 2 responses and then for the other calls I will get 503 services unavailable.

what is wrong with my code?

EDIT I have read this article How to configure concurrency in .NET Core Web API?, the problem is when I add the web.config

 <configuration>
    <system.web>
        <applicationPool
            maxConcurrentRequestsPerCPU="5000"
            maxConcurrentThreadsPerCPU="0"
            requestQueueLimit="5000" />
    </system.web>
</configuration>

i have the warning

the element system. web has invalid child element applicationpool

and i cannot publish the api on iis or run it in iis express

Upvotes: 1

Views: 18958

Answers (3)

Craig Wayne
Craig Wayne

Reputation: 5068

.NET 7 has support for rate limiting

in your Program.cs file

using System.Threading.RateLimiting;
using Microsoft.AspNetCore.RateLimiting;

builder.Services.AddRateLimiter(rateLimiterOptions =>
{
    rateLimiterOptions.RejectionStatusCode = StatusCodes.Status429TooManyRequests;;
    rateLimiterOptions.AddFixedWindowLimiter("fixed-window", fixedWindowOptions =>
    {
        fixedWindowOptions.Window = TimeSpan.FromSeconds(5);
        fixedWindowOptions.PermitLimit = 5;
        fixedWindowOptions.QueueLimit = 10;
        fixedWindowOptions.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
    });
});

...

app.UseRateLimiter();

in your Controller file

using Microsoft.AspNetCore.RateLimiting;
...
[ApiController]
[Route("[controller]")]
[EnableRateLimiting("fixed-window")] // add this attribute
public class WeatherForecastController : ControllerBase
{
   ...
}

References:

Upvotes: 4

victorm1710
victorm1710

Reputation: 1523

Option serverOptions.Limits.MaxConcurrentConnections limits maximum number of tcp connections to Kestrel, not the number of concurrent http requests. Through each tcp connection there still might be multiple concurrent http requests. That's why in your test you can see no errors, even though there are more than 2 concurrent http requests.

In order to limit the number of concurrent http requests in .NET Core (or .NET 5+), you can use ConcurrencyLimiterMiddleware (package Microsoft.AspNetCore.ConcurrencyLimiter). Here is an example:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddStackPolicy(options =>
        {
            options.MaxConcurrentRequests = 2;
            options.RequestQueueLimit = 25;
        });
    }

    public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
    {
        app.UseConcurrencyLimiter();
    }
}

Upvotes: 5

Zhi Lv
Zhi Lv

Reputation: 21656

Since the API will host in the IIS, so, the configuration for the Kestrel will not be used.

To set the max concurrency connections in IIS, you could Open IIS manager window. Select the site from the server node. Then, select Advance setting from the action pane. You can see the Limits under the Behavior section. Set Maximum Concurrent Connection value based on your requirement. Like this:

enter image description here

[Note] This setting is for all Sites.

Besides, you could also check this sample and create a custom middleware to limit the request.

Upvotes: 3

Related Questions