Net 7 ile gelen Rate Limiter özelliği

Vedat ERMIS
Kariyer.net Tech
3 min readFeb 8, 2023

--

.Net 7 beraberinde yepyeni özellikler ile sonunda Release oldu. Bende bu makalemde yeni bir özellik olan Rate Limiting özelliğini anlatıyor olacağım.

İlk önce Rate limit’ in ne olduğunu anlamaya çalışalım. Bir web servisimiz olduğunu düşünelim bizim servisimizin temel görevi gelen her isteği cevaplayarak geriye bir sonuç döndürmesidir. Bizim servisimize gelen istek sayıları arttıkça servisin cevap verme süresi de doğru oranda artıyor olacaktır ve bir süre sonra servisimiz artık isteklere cevap veremiyor duruma gelecektir. Biz bu sorunu engellemek için çeşitli Api gateway araçları ile aynı IP’ den gelen isteklere bir limit getirerek çözebiliyoruz. Artık .Net 7 ile bu durumu herhangi bir gateway kullanmadan çözebiliyoruz.

Net 7 ile birlikte gelen toplamda 4 adet Rate Limiter algoritması bulunmaktadır. Şimdi bu algoritmalardan kısaca bahsederek birer örnek yapalım.

Fixed Windows Algoritması

Belli bir zaman aralığında gelen istekleri sınırlayan bir algoritmadır.

builder.Services.AddRateLimiter(options =>
{
options.AddFixedWindowLimiter("FixedWindow", opt =>
{
opt.Window = TimeSpan.FromSeconds(5);
opt.QueueLimit = 3;
opt.PermitLimit = 5;
opt.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
});
});

app.UseRateLimiter();

Bu kod örneğinde kullandığımız özellikleri de açıklayalım;
Window: Zaman aralığı
PermitLimit: Belirtilen zaman aralığında işlenecek istek sayısı
QueueLimit: Belirtilen zaman aralığında işlenecek istek sayısından sonra gelen kaç tane isteği kuyruğa koyacağımızı burda belirtiyoruz. Bu adetten sonraki istekler işlenmeyecektir.
QueueProcessingOrder: Kuyruktaki isteklerin hangi sırada işleceniğini belirtiyoruz.

Sliding Window Algoritması

Bulunduğu periyodun yarısından sonra bir sonraki periyodun kotasından harcayan bir algoritmadır. Biraz daha açıklamak gerekirse ;

Periyodumuz 10 saniye olsun ve her periyotta da en fazla 5 istek karşılıyor olalım. Periyodumuzun ilk 5 saniyesinde 4 request karşıladıysak, sonraki 5 saniye de ise 2 istek daha karşılayabiliriz. Burada 1 istek bir sonraki periyottan borç alınmış oldu.

builder.Services.AddRateLimiter(_ => _
.AddSlidingWindowLimiter(policyName: "SlidingWindow", options =>
{
options.PermitLimit = 5;
options.Window = TimeSpan.FromSeconds(10);
options.SegmentsPerWindow = 1;
options.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
options.QueueLimit = 4;
}));

app.UseRateLimiter();

Bu kod bloğundaki SegmentsPerWindow değeri, kendisinden önceki periyoda kaç isteği borç vereceğini belirtir.

Token Bucket Algoritması

Bu algoritmada her isteğe karşılık bir token üretilir. Eğer periyod için belirtilen token’lar tükenirse, bir sonraki periyottan borç alınır.

builder.Services.AddRateLimiter(_ => _
.AddTokenBucketLimiter(policyName: "tokenPolicy", options =>
{
options.TokenLimit = 10;
options.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
options.QueueLimit = 5;
options.ReplenishmentPeriod = TimeSpan.FromSeconds(5);
options.TokensPerPeriod = 5;
options.AutoReplenishment = true;
}));

app.UseRateLimiter();

Eğer AutoReplenishment true olarak ayarlarsak, dahili bir zamanlayıcı her ReplenishmentPeriod süresinde belirteçleri yeniler.

ReplenishmentPeriod değeri periyotları ne kadarlık süreye böleceğimizi belirtir.

Concurrency Limiter Algoritması

Bu algoritma sadece asenkron çalışan istekleri sınırlandırmak için kullanılan algoritmadır. Belirlediğimiz istek sınırı 5 olsun. Her istek geldiğinde bu sınırı 1 azaltır, istek sonuçlandığında ise sınırı 1 arttırır. Yani sınırımız 5. Bir istek geldi sınırımız 4' e indi gelen istek sonuçlandığında ise sınırımız tekrar 5' e yükselmiş oldu.

builder.Services.AddRateLimiter(_ => _
.AddConcurrencyLimiter(policyName: "concurrencyPolicy", options =>
{
options.PermitLimit = 5;
options.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
options.QueueLimit = 3;
}));

app.UseRateLimiter();

Peki bu algoritmaları endpoint’lerimizde nasıl kullanacağız ?

Bunun için ya endpoint bazında yada action bazında attribute yazarak devreye sokabiliriz.

    [HttpGet(Name = "GetWeatherForecast")]
[EnableRateLimiting("tokenPolicy")]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}

Kaynakça
https://learn.microsoft.com/en-us/aspnet/core/performance/rate-limit?view=aspnetcore-7.0

--

--