With the upcoming
.NET 7, there's a new NuGet package System.Threading.RateLimiting coming to manage the Rate Limiting. We can use rate limiting to protect
a resource from getting overwhelmed. There is a very detailed post
Announcing Rate Limiting for .NET that you definitely should read.
In this post, let's see how can we use Rate Limiting quite easily with an
ASP.NET Core Application. You need to install Microsoft.AspNetCore.RateLimiting NuGet package that provides ASP.NET Core middleware for enforcing rate limiting in an application using System.Threading.RateLimiting.
Once that's installed, we need to start by defining RateLimiterOptions.
RateLimiterOptions rateLimiterOptions = new();
Here you can set up variety of things such as defining a GlobalLimiter,
adding individual rate limiters and customizing the behavior when a request is
rejected from a Rate Limiter.
Now let's start by adding ConcurrencyLimiter, one of the inbuilt rate limiters.
rateLimiterOptions.AddConcurrencyLimiter(policyName: "ConcurrencyLimit", new ConcurrencyLimiterOptions(permitLimit: 5, queueProcessingOrder: QueueProcessingOrder.OldestFirst, queueLimit: 3));
Next, we need to enable Rate Limiting middleware and use the RateLimiterOptions we just created.
app.UseRateLimiter(rateLimiterOptions);
Next, we can use rate limiters we have configured in our endpoints, something
like below.
app.MapGet("/ToDos", () => { return TypedResults.Ok(); }) .RequireRateLimiting("ConcurrencyLimit");
Here note: the global limiter will be executed first, followed by
the endpoint-specific limiter, if one exists.
Now let's try to hit the rate limit on the above endpoint by making parallel
requests (a lazy way of course).
HttpClient _httpClient = new HttpClient { BaseAddress = new Uri("https://localhost:44378"), }; List<Task<HttpResponseMessage>> tasks = new List<Task<HttpResponseMessage>>(); for (int i = 0; i < 10; i++) { Task<HttpResponseMessage> task = _httpClient.GetAsync("/Todos"); tasks.Add(task); } var results = new List<HttpResponseMessage>(await Task.WhenAll(tasks)); foreach (HttpResponseMessage item in results) { Console.WriteLine(item.StatusCode); }
And I can see an output like below.
ServiceUnavailable |
rateLimiterOptions.RejectionStatusCode = (int)HttpStatusCode.TooManyRequests;
Most importantly, a must-read.
Happy Coding.
Regards,
Jaliya
No comments:
Post a Comment