1

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

dimmits
  • 1,999
  • 3
  • 12
  • 30
  • I have read this answer but when I add the web.config cannot publish or run it is iis express.i get the error element system. web has invalid child element applicationpool – dimmits Jan 12 '21 at 08:50
  • please read the edit – dimmits Jan 12 '21 at 09:32

3 Answers3

4

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.

Zhi Lv
  • 18,845
  • 1
  • 19
  • 30
  • thank you very much @Zhi Lv, I did the mistake to change the application pool queue – dimmits Jan 14 '21 at 14:20
  • @zhi-lv Solution for linux ? I run like dotnet run app.dll --url://0.0.0.0:5000 ? It is behind haproxy loadbalncer. But server hangs if req rate > 20/sec with 10% cpu usage. How do we increase these parameters ? – Khurshid Alam Aug 24 '23 at 23:25
  • @KhurshidAlam my solution is for Windows Server and IIS, instead of linux. – Zhi Lv Aug 25 '23 at 09:40
4

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();
    }
}
victorm1710
  • 1,263
  • 14
  • 11
1

.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:

Craig Wayne
  • 4,499
  • 4
  • 35
  • 50