Bu yazımda, .NET 7 ile gelen Rate Limiting middleware yapısı ve kullanımına değinilecektir. Öncelikle Rate Limiting'in ne olduğuna değinecek olursak;
Rate Limiting,
"belirli bir zaman diliminde; uygulamaya yapılan istek sayısının
sınırlandırılmasıdır" ve bu amaçla uygulanan algoritmalar bulunur.
Geliştirici olarak API entegrasyonu yaparken veya son kullanıcı olarak
istek yaparken, 429 hata kodu bulunan veya
"Too Many Request" mesajlı bir
uyarı gördüğünüzde yapabileceğiniz istek sınırına ulaşmış olup, daha
fazlasına izniniz yok demektir. Bu sınırlamayı yapan yaklaşım, rate
limiting'dir.
Client Server Rate Limiting İlişkisi
Güvenlik, kaynakların doğru yönetimi, uygulamanın çökmesini engelleme ve
sunucu trafiğinin kontrol altına alınması yönünden kritik bir konudur.
1 Temmuz 2023 tarihinde, Twitter'da uygulandığı açıklanan tweet
görüntüleyebilme sınırını uygulayan yaklaşım da aynıdır.
"Rate Limiting Kavramını ve Algoritmalarını Anlamak"
konulu yazımda rate limiting algoritmalarına detaylı olarak değinilmiştir.
Okumak için
tıklayınız.
Bu yazımda, Rate Limiting kavramının .NET
teknolojisinde nasıl uygulandığına değinilmektedir.
.NET 7 ile built-in-middleware olarak gelen RateLimiting, .NET 7'den önce
third party kütüphanelerin projelere dahil edilmesi veya custom middleware
yazılmasını gerektirirdi.
.NET 7 de aşağıdaki Nuget paketleri, bu özelliği sağlamaktadır.
-
Microsoft.AspNetCore.RateLimiting
- System.Threading.RateLimiting
Örnek bir projede incelemek gerekirse;
API projesi oluştururken minimum versiyon olarak .NET 7 seçili
olmalıdır.
Proje oluştuktan sonra,
Program.cs dosyasına
UseRateLimiter()
middleware metodu dahil edilmelidir. Bu metot, uygulamada Rate Limiting'i aktif
eder.
Aktifleştirdikten sonra
builder.Services.AddRateLimiter servis metodu dahil edilecektir.
Bu metotla rate limiting servisleri ve içerisine policy tanımlanarak
yapılandırma işlemi gerçekleştirilir.
RateLimiterOptions türünden
yapılandırma parametresi geçilir.
- Hangi algoritma kullanılacağı,
- İstek sınırlandırma işlemleri,
-
İstek reddedildiğinde nasıl dönüş yapılacağının
yapılandırması burada yapılır.
AddRateLimiter metodundaki
options içerisinde kullanılan;
options.RejectionStatusCode: İstek reddedildiğinde gösterilecek hata durum kodu ayarlanır.
Varsayılan olarak 500 olacaktır. En iyi kullanım olarak 429 verilebilir.
options.OnRejected: İstek reddedildiğinde olay mantığında çalışacak işlemler tanımlanır.
Loglama işlemi yapmak istersek çözüm olabilir.
options.RateLimiter:
Rate Limiting algoritmalarının ve yapılandırmalarının belirtileceği
yerdir.
Burada kullanılan ve temel rate
limiting algoritmalarına karşılık gelen metotları tanıtmaya gelince;
AddFixedWindowLimiter()
Bu metot,
Fixed Window algoritmasının
uygulanmasıdır.
Belirlenen sabit zaman aralığında istek limitine ulaşıldığında, bir
sonraki zaman penceresine kadar gelen istekler reddedilecektir.
Metotta kullanılan parametreler;
policyName: Fixed Window
olarak oluşturulan policy'e verilen isim. API controller veya action
metotlarda kullanılacaktır.
configureOptions: Yapılandırma
ayarları burada tanımlanır.
Action<FixedWindowRateLimiterOptions>
türündedir.
-
options.Window: İsteklerin
gerçekleşeceği zaman aralığıdır. TimeSpan türünden değer
atanır.
-
options.PermitLimit: Window
property'sindeki zaman aralığında kabul edilecek istek adeti.
-
options.QueueLimit: Eğer belli
bir zaman aralığında maksimum istek sayısına ulaşıldığında kuyruğa ne
kadar istek alınabileceği tanımlanır.
-
options.QueueProcessingOrder: Kuyrukların işlenme sırası belirtilir. Değer olarak Kuyruğa ilk
gelenin ilk işleneceği
OldestFirst veya kuyruğa
en son girenin ilk işleneceği
NewestFirst enum atanır.
Örnek kodda, Fixed Window algoritması kullanarak sistemin 60 saniye
içerisinde en fazla 12 isteği kabul edeceği ve 12 den fazla istek
geldiğinde kuyruğa da en fazla 2 isteği dahil edeceğini ifade ederiz.
Kuyruğa eklenen isteklerden de ilk gelenin işlenebileceği tanımlandı.
AddSlidingWindowLimiter()
Bu metot, Sliding Window algoritmasının uygulanmasıdır.
İstekleri sabit bir zaman penceresinde sınırlamaz. Gelen istekler,
istek zamanıyla birlikte bir dizi yapısında tutulur.
Metotta kullanılan parametreler;
policyName: Sliding Window olarak oluşturulan policy'e verilen isim. API controller veya action metotlarda
kullanılacaktır.
configureOptions:Yapılandırma ayarları burada tanımlanır.
Action<SlidingWindowRateLimiterOptions> türündedir. Ortak parametrelerden farklı olan özellikler ise;
-
options.SegmentPerWindow: İsteklerin gerçekleşme zamanının kaç eşit parçaya bölüneceğini
belirtir. Yukarıdaki görselde 10 saniyelik zaman penceresinin 1
eşit parçaya bölündüğü ve 10 saniyede 50 istek kabul edileceğini
belirtir.
AddTokenBucketLimiter()
Bu metot, Token Bucket algoritmasının uygulanmasını sağlar.
Belirli bir periyotta belirli bir sayıda istek yapabileceğini
belirleriz.
Metotta kullanılan parametreler;
policyName: Token Bucket olarak oluşturulan policy'e verilen isim. API
controller veya action metotlarda kullanılacaktır.
configureOptions:Yapılandırma ayarları burada tanımlanır.
Action<TokenBucketRateLimiterOptions> türündedir. Ortak parametrelerden farklı olan özellikler ise;
-
options.TokenPerPeriod: Her yenilenme zamanında eklenmesi istenen maksimum istek
limitidir.
-
options.TokenLimit: Herhangi bir zamanda belirtilen en fazla istek limitidir.
Örnek olarak;
TokenPerPeriod=7
ve TokenLimit=10 olan bir problemde her yenilenme zamanında 7 adet istek limiti
olacaktır. İsteğin başında 10 verilmektedir. Eğer istek artarsa
yenilemede, 7 olarak sınır belirtilir.
AddConcurrencyLimiter()
Bu metot, sadece asenkron istekleri sınırlandırmamızı
sağlar.
Metotta kullanılan parametreler;
policyName: Concurrency Limiter olarak oluşturulan policy'e verilen isim. API
controller veya action metotlarda kullanılacaktır.
configureOptions:Yapılandırma ayarları burada tanımlanır.
Action<ConcurrencyLimiterOptions> türündedir.
-
options.PermitLimit: Asenkron olarak en fazla gerçekleşebilecek istek adetidir.
Örneği daha iyi anlayabilmek için örnek bir kod yapısına
Task.Delay ile 10
saniye bekletme yapılan bir iş kuralı oluşturup birden fazla
sekmede aynı endpointi çağırabilirsiniz.
Attribute - Özellikler
Rate Limiting politikalarının uygulanabilmesi için aktif ve pasif
yapılabilen iki adet attribute bulunur. Bunlar, controller ve metot
seviyelerinde tanımlanabilir.
Controller seviyesinde tanımlananlar, o controller altındaki
bütün endpointlerde geçerlidir.
Metotlarda tanımlananlar ise o endpointler için geçerlidir.
EnableRateLimiting:
Program.cs'de tanımlanan ratelimiter politikasının ismini parametre
olarak vererek controller veya metotta kullanılmasını sağlar.
DisableRateLimiting:
RateLimiting kullanılmasını engeller. Aşağıdaki görselde bulunan
endpoint için rate limiting çalışmayacaktır.
Bonus:
Minimal API'de kullanmak için
RequireRateLimiting metoduna parametre olarak policy ismi verildikten sonra
çalışacaktır.
RateLimiting yapısını kısaca tanımlayarak .NET 7 ile yapılandırılması
ve kullanımına değinilmiştir.
Örnek Github reposuna ulaşmak için
buraya tıklayabilirsiniz.
Keyifli ve faydalı olmasını umarak, çalışmalarınızda kolaylıklar
diliyorum.
Yazımı yazarken incelediğim kaynaklar,
Yorumlar
Yorum Gönder